如何在第一场比赛后终止“查找”?

如何在第一场比赛后终止“查找”?

我在 while 循环中使用 find 。它获取 ip.txt 中的 IP 列表,在文件目录中搜索 IP,然后将找到的每个 IP 的文件名写入名为 results.res 的文件中

我想在每次成功找到后停止并移动到下一个IP。

我当前的脚本是:

while read ip; do
    find . -type f -maxdepth 1 -not -name ips.txt -not -name results.res -print0  | xargs -0 grep "$ip" >> results.res
done < ips.txt

我研究了网站上的其他答案,发现使用

-print -quit
-print | head -n 1

在第一次成功找到后停止查找,但是因为我使用的是 while 循环,所以这不起作用,有人可以建议一个可行的解决方案吗?

答案1

while IFS= read -r ip; do
  find . -maxdepth 1 \
         -type f \
         ! -name ips.txt \
         ! -name results.res \
         -exec grep -lwFe "$ip" {} \; \
         -quit
done < ips.txt > results.res

将文件的每一行读ips.txt$ip变量并浏览匹配条件的文件find(无特定顺序),报告包含$ip固定F字符串和word 分隔的第一个文件。当成功-quit时调用-exec,即grep返回一个真的找到匹配项时退出状态。

答案2

按照当前编写脚本的方式,它将运行find,然后运行它找到的每个文件,以及它在 中找到的grep每个文件。 ipips.txt

您不需要find每次都运行来获取相同的文件列表,因此将其从while循环中取出并将其分配给一个变量。您也不需要grep为找到的每个文件都运行,您可以通过一个命令搜索所有文件。现在您已经有了文件列表,您可以grep为每个文件执行 aip并仅返回第一个匹配项。所以脚本现在看起来像这样:

files=$(find . -maxdepth 1 -type f -not -name ips.txt -not -name results.res)
while read ip; do
    grep --with-filename --max-count=1 "$ip" $files | head -n 1 >> results.res
done < ips.txt

这将grep遍历每个infind命令中的每个文件,并且应将包含每个 IP 地址的行以及在其中找到它的第一个文件放入. ipips.txtresults.res

编辑:

经过一些测试,似乎确实有更好的方法,因为前面的代码根本不处理带有空格或奇数字符的文件名。所以我要摆脱它,find因为这里似乎没有必要。

您计划grep遍历当前目录中除results.res和 之外的所有文件ips.txt,因此您可以使用grep而不查找:

while read ip; do
    grep --with-filename --max-count=1 --exclude={results.res,ips.txt} "$ip" * | head -n 1 >> results.res
done < ips.txt

相关内容