在 bash 中使用 && 在输出中查找两个字符串

find two strings in output with && in bash

我想查找两个字符串(如果它们存在于我的输出中)然后通过管道将它们作为参数传递给下一个命令。

例如:

for X = 1 to 100
    cat logX.txt | grep -e string1 -e string2 | rm logX.txt

但我不知道如何实现上述目标。

我必须检查这 100 个文件并删除其中包含这两个字符串的文件。如果存在任何字符串,那么我不想删除文件。

如果您只想删除具有两个匹配项的文件,awk——作为一种成熟的编程语言,可以给出一个独立检查标志的表达式——比[=更合适13=](它根据是否找到 any 匹配修改其退出状态,而不是是否匹配给定的 all 表达式)。

string1="first regex"
string2="second regex"
for ((x=1; x<=100; x++)); do
  file="log$x.txt"
  awk -v string1="$string1" -v string2="$string2" '
    BEGIN { found1=0; found2=0; }
    [=10=] ~ string1 { found1=1; }
    [=10=] ~ string2 { found2=1; }
    END { exit(!(found1 && found2)) }
  ' "$file" && rm -f -- "$file"
done

等效的grep效率会低得多,因为它必须读取每个文件两次:

# MUCH SLOWER ON BIG FILES: Reads each file twice (up to the point where a match exists)
string1="first regex"
string2="second regex"
for ((x=1; x<=100; x++)); do
  file="log$x.txt"
  grep -q -e "$string1" -- "$file" && grep -q -e "$string2" -- "$file" && rm -f -- "$file"
done

您可以使用 find 来做到这一点:

find . -name 'log*.txt' -exec grep -E 'string1' {} \; -exec grep -E 'string2' {} \; -exec rm {} \;

这会找到 logN.txt,对字符串 1 进行 grep,如果匹配则对字符串 2 进行 grep,如果匹配则删除文件。

根据下面的评论,如果您只想在当前目录中查找文件,请添加 -maxdepth 1

使用 GNU 并行:

parallel 'grep string1 log{}.txt && grep string2 log{}.txt && rm log{}.txt' ::: {1..100}

如果您想查看所有 log*.txt 文件,那么这个更短:

parallel 'grep string1 {} && grep string2 {} && rm {}' ::: log*.txt