通过搜索特定文件扩展名对目录进行排序

通过搜索特定文件扩展名对目录进行排序

假设我在一个目录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")

相关内容