假设我在一个目录A中,A下有很多文件夹(B、C、D等),每个文件夹中有一个文件“*.out”和子文件夹。我想从 A 运行一个脚本,它将在 *.out 文件中查找文本“index123”并打印出所有相应的文件夹名称。
这是我的脚本:
#!/bin/sh
FILES=home/A
grep --include=\*.out -rnw $FILES -e "index123" | while read file; do
str1="FILES/$(basename $file)"
echo $str1
done
这显示错误。
注意:这可以通过在一行代码中“查找”来完成,但是为什么显示的 while 循环显示错误?
答案1
假设目录结构如下:
A
|-- B
| |-- file1.out
| |-- file2.out
| `-- file3.out
|-- C
| |-- file1.out
| |-- file2.out
| `-- file3.out
|-- D
| |-- file1.out
| |-- file2.out
| `-- file3.out
`-- E
|-- file1.out
|-- file2.out
`-- file3.out
您的代码的问题是您grep
将产生如下所示的输出
./B/file1.out:2:some data which includes the word index123
./B/file2.out:2:some data which includes the word index123
./B/file3.out:2:some data which includes the word index123
./C/file1.out:2:some data which includes the word index123
./C/file2.out:2:some data which includes the word index123
./C/file3.out:2:some data which includes the word index123
./D/file1.out:2:some data which includes the word index123
./D/file2.out:2:some data which includes the word index123
./D/file3.out:2:some data which includes the word index123
./E/file1.out:2:some data which includes the word index123
./E/file2.out:2:some data which includes the word index123
./E/file3.out:2:some data which includes the word index123
这就是输出
grep --include=\*.out -rnw . -e "index123"
以A
作为当前目录。
然后,您将尝试在这些单独的行上运行basename
,这会失败,因为basename
最多需要两个参数(路径名和从该路径名中删除的后缀)。 GNUbasename
会抱怨“额外的操作数”,而 BSDbasename
会抱怨不正确的使用。
grep
当您将其与标志一起使用时,将显示文件的名称(仅显示,即不显示匹配的完整行)-l
。
这意味着您的脚本可能会被单个命令替换
grep -w -l "index123" */*.out
这将在表单上给出输出
B/file1.out
B/file2.out
B/file3.out
C/file1.out
C/file2.out
C/file3.out
D/file1.out
D/file2.out
D/file3.out
E/file1.out
E/file2.out
E/file3.out
我添加了-w
您在grep
命令行中使用的内容。-n
(用于编号行,您也在使用)不能与一起使用-l
。
从你的代码来看,这就是你想要的。
如果您只需要文件夹名称,请执行以下操作
$ grep -w -l "index123" */*.out | sed 's#/[^/]*##' | sort -u
B
C
D
E
所有这些都假设这A
是当前工作目录,但您说问题就是这种情况,所以这不应该是问题。
答案2
根据帖子通过 while 循环中的特定搜索查找文件解决方案之一可以通过使用循环如下while
:
#!/bin/bash
while IFS= read -r d;
grep -q "index123" "$d" && dirname "$d"|awk -F'/' '{print $2}'
done < <(find . -maxdepth 2 -type f -name "*.out")