通过 while 循环中的特定搜索查找文件

通过 while 循环中的特定搜索查找文件

其实和我之前的帖子有关系通过搜索特定文件扩展名对目录进行排序这仍然没有答案。有很多选项可以解决这个问题,但我对while循环特别感兴趣。在当前工作目录中,我想通过循环扫描某些内容来搜索特定文件的存在while,然后仅打印相应的文件夹名称。当前工作目录有许多文件夹和子文件夹。这是我的脚本:

while IFS= read -r d; do  
   if [[ "$d"=="*.out" && grep "index123"]]; then exit 1;  fi  
done <<  (find . -prune -type d) 

我不知道强加是否if是在循环内执行的正确方法或其他方法。请指导。

答案1

为什么 grep 失败

在终端中执行此操作:

失败 - 等待输入
$ grep "index123"
工作 - 接收来自 STDIN 的输入
$ echo -e "line1\nline2\nindex123blah\n" | grep "index123"
index123blah

第二个之所以有效,是因为我们提供了grep通过 STDIN 进行解析的输入。grep将从 STDIN 或文件获取输入。在你的场景中:

if [[ "$d"=="*.out" && grep "index123"]]; then exit 1;  fi  

它也没有解析,因此失败了。

你的问题

从你的代码来看,我相信你想要这样的东西。首先,这里有一些示例数据:

$ mkdir -p 1/2/{3..5}
$ echo "index123" > 1/2/3/blah.out
$ echo "index123" > 1/2/3/blip.out
$ echo "index" > 1/2/blip.out
$ echo "index" > 1/2/blah.out

以及脚本的修改形式:

$ cat loopy.bash
#!/bin/bash

while IFS= read -r d; do  
  grep -l "index123" "$d" && exit 1
done < <(find . -type f -name "*.out") 

跑步:

$ ./loopy.bash
./1/2/3/blah.out

发出它发现的第一个包含index123字符串的文件,然后退出。

while循环有一个好的解决方案吗?

我不会这样做。while没有必要以这种方式使用循环。最好使用find .... | xargs ...架构或find ... -exec解决方案类型。

@DopeGhoti 的回答以获得更好的方法来使用find-execxargs

打印包含目录

如果您只想打印匹配文件所在的包含目录树,您可以dirname像这样执行此操作:

$ cat loopy2.bash
#!/bin/bash

 while IFS= read -r d; do
   grep -q "index123" "$d" && dirname "$d"  && exit 1
 done < <(find . -type f -name "*.out")

并运行它:

 $ ./loopy2.bash
./1/2/3

答案2

这是你的问题:

if [[ "$d"=="*.out" && grep "index123"]];

让我们假设一下d=foo.out。我们现在有效地拥有:

if [[ grep "index123"]];

所以你试图告诉在grep标准输入中搜索表达式/index123/。但是不会有任何输入到达它,因此它在等待输入时会(似乎)挂起。然而,它甚至不会走那么远,因为if [[ grep "index123" ]]从表面上看语法无效。相反,你会想要if grep "index123".但同样,这只是等待标准输入的到来。

看来您想要返回包含文本的find名为 的文件。所以试试这个:*.outindex123

find . -prune -type d -name \*.out -print0 | xargs -0 grep -l 'index123'

不过,这个find说法相当复杂。find当我们可以搜索我们想要的实际文件时,为什么要一切都然后修剪目录呢?

find . -type f -name \*.out -print0 | xargs -0 grep -l 'index123'

现在您将看到包含您要查找的文本的所有文件。

不过,我们甚至不需要带到xargs桌面上,因为可以单独find调用:grep

find . -type f -name \*.out -exec grep -l 'index123' "{}" \;

答案3

查找当前目录中*.out包含该字符串的所有文件:index123

grep -lF 'index123' ./*.out

如果您想grep对所有*.out文件进行递归,无论它们位于当前目录下的哪个位置:

find . -type f -name '*.out' -exec grep -lF 'index123' {} +

打印找到该字符串的目录:

find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';'

第一次找到目录名称后退出(使用 GNU find):

find . -type f -name '*.out' -exec grep -qF 'index123' {} ';' -exec dirname {} ';' -quit

取决于您接下来的计划使用的目录名称,您可以用-quit另一个替换-exec来以您需要的任何方式处理该目录,或者将各种-exec实用程序组合到名为 from 的 shell 脚本中-exec。你是什​​么不是所做的是将目录名通过管道传递给其他命令,因为这通常是不安全的,除非您在使用 nul 字符分隔路径名时采取额外的预防措施。

有关的:

相关内容