如何在 bash 中使用 && 与 grep



我想检查文件中是否存在 bash 中的多行。

因此,为此,我使用仅适用于一行的grep -q

if grep -q string1 "/path/to/file";then
echo 'exists'
else
echo 'does not exist'
fi

我尝试了许多不同组合的东西,例如:

if grep -q [ string1 ] && grep -q [ string2 ] "path/to/file";then

我也用-E试过了:

grep -E 'pattern1' filename | grep -E 'pattern2'

但似乎没有任何效果。有什么想法吗?

您可以使用以下gnu-awk命令来断言文件中存在多个字符串,而不是运行多个grep命令:

awk -v RS='\Z' '/string1/ && /string2/ && /string3/{e=1} END{exit !e}' file &&
echo 'exists' || echo 'does not exist'
  • RS=Z将使awk在单个记录分隔符中读取所有输入
  • 在多个搜索词之间使用&&将确保输入文件中存在所有搜索词
  • 仅当输入文件中存在所有 3 个搜索词时,才会打印exists

由于@iruvar没有将他的评论作为答案,我将把它放在这里:

grep -q string_1 file && grep -q string_2 file

现在,这是我的贡献。 @anubhava计算更复杂的awk答案(只读取文件一次)是否比@iruvar更简单的答案(读取文件三次)更快?

awk          11.730 s
grep && grep  0.258 s

不。

这肯定取决于文件系统与 CPU 的速度,以及缓存的进行量,但在我的系统上,这可能是一个典型的 B+/A- 工作站,grep kw1 file && grep kw2 file && grep kw3 file的速度是 @anubhavaawk解决方案的 ~50 倍。 这在SSD和Spindle RAID上都是如此。(详细信息:测试文件为 5,000,000 行,160M,第一行有kw1,第 250 万行有kw2,第 500 万行有kw3

一些简单的优化是可能的,例如,如果你可以通过匹配整行来解决问题,那就这样做(用grep -x);在这种情况下,它的速度是原来的两倍。

对于许多(例如,>1,000)文件,使用grep -lxargs会更快:

grep -l kw1 *.txt | xargs grep -l kw2 | xargs grep -q kw3

与循环相反:

for f in *.txt; do
grep -q kw1 $f && grep -q kw2 $f && grep -q kw3 $f
done

使用相同的测试文件,grep -l | xargs grep花费了 0.258 秒,就像grep && grep一样。 使用两个测试文件,它仍然不比grep && grep快。 有 2000 个测试文件,每个 5,000 行,其中没有一个包含任何匹配项,grep -l | xargs grepgrep && grep快 ~10 倍。

你的问题中有一些歧义,但假设您希望pattern_1和pattern_2存在于文件中(不在同一行上),那么你可以这样做。

for file in *; do
egrep -q pattern_1 $file && egrep -q pattern_2 $file && echo $file
done

使用grep -p您可以在同一行中匹配乘法模式:

grep -P '(?=.*string1)(?=.*string2)' file

以上将打印与string1string2匹配的行。

(?=...)是一个积极的展望,它与模式相匹配,而不会使其成为比赛的一部分。

-z将啜饮整个文件:

% seq 1 100 | grep -qzP '(?=.*1)(?=.*5)'; echo $?
0
% seq 1 100 | grep -qzP '(?=.*1)(?=.*a)'; echo $?
1

你可以这样做:

if grep -q 'string1' /path/to/file; then
if grep -q 'string2' /path/to/file; then
echo exists
else
echo 'does not exist'
else
echo 'does not exist'
fi

或:

grep -q 'string1' /path/to/file &&
grep -q 'string2' /path/to/file &&
echo exists ||
echo 'does not exist'

您可以使用"-q"使用grep进行搜索

if  grep -q string1 "/path/to/file" &&  grep -q string2 "/path/to/file";then
echo 'exists'
else
echo 'does not exist'
fi 

相关内容

  • 没有找到相关文章

最新更新