其实和我之前的帖子有关系通过搜索特定文件扩展名对目录进行排序这仍然没有答案。有很多选项可以解决这个问题,但我对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
或-exec
。xargs
打印包含目录
如果您只想打印匹配文件所在的包含目录树,您可以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
名为 的文件。所以试试这个:*.out
index123
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 字符分隔路径名时采取额外的预防措施。
有关的: