我想检查文件中是否存在 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 -l
和xargs
会更快:
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 grep
比grep && 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
以上将打印与string1
和string2
匹配的行。
(?=...)
是一个积极的展望,它与模式相匹配,而不会使其成为比赛的一部分。
-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