我有几行(我不知道有多少行)。我通过管道将它们发送到grep
。我需要找出grep
是否选择了所有行。然后我需要写好(如果他们都被选中)或不好。我怎么能这样做?
答案 0 :(得分:5)
一种方法是使用-v
(--invert-match
)标记,该标记告诉grep
搜索不匹配您的模式的行
您可以将其与-q
(--quiet
或--silent
)标志结合使用,该标志告诉grep
实际上不会发出任何输出,并且只是成功退出找到 输出的任何行。
然后你可以检查退出状态:零("成功" /"真")如果任何行不匹配你的模式,非零("失败" /"假")否则。所以:
if ... | grep -qv ... ; then
echo Not OK
else
echo OK
end
答案 1 :(得分:0)
如果您有两个文件a b c
和file1
,则可以检查file2
的所有行是否都在file1
中:
file2
如果if ! grep -qvxFf file2 file1; then
echo "All lines of file1 are present in file2'
else
echo "Some lines of file1 are not present in file2'
fi
来自命令执行,则使用进程替换:
file1
if ! grep -qvxFf file2 <(file1-command); then
echo "All lines are present in file2'
else
echo "Some lines are not present in file2'
fi
匹配整行x
将这些行视为字符串,而不是模式当F
中的所有行与file1
中的至少一行匹配时,file2
会提供退出代码1,表示该匹配未返回任何输出grep -qvxFf file2 file1
(反向)匹配)生效。
答案 2 :(得分:0)
如果我理解正确,你现在有:
some-process-generating-lines |
grep -e 'some selection criterion'
并且你想检查传递到grep
的行数是否与从它出来的行数相同 - 是否每个输入行都满足选择标准。
您需要能够计算线路和线路输出。计算行很容易 - 通过wc -l
传递输出并捕获整个结果。
lines_out=$(some-process-generating-lines |
grep -e 'some selection criterion' |
wc -l)
计算线条是适度的。最简单的方法是让tee
命令创建输入数据的副本到grep
,然后计算:
tmpfile=$(mktemp ${TMPDIR:-/tmp}/soq.XXXXXXXX)
trap "rm -f $tmpfile; exit 1" 0 1 2 3 13 15
lines_out=$(some-process-generating-lines |
tee $tmpfile |
grep -e 'some selection criterion' |
wc -l)
lines_in=$(wc -l <$tmpfile)
rm -f $tmpfile
trap 0 1 2 3 13 15
if [ "$lines_in" = "$lines_out" ]
then echo OK
else echo Not OK
fi
trap
内容确保(或尝试确保)临时文件被清除,即使进程被中断(或发送退出,挂起,管道或终止信号)。 mktemp
命令生成唯一的文件名。其余的相当直接,我相信。
答案 3 :(得分:0)
假设您的问题由此定义:
some-process-generating-lines |
grep -E 'some selection criterion'
你要计算进出线数,你可以这样做:
printf "aaa\nbbb\nccc\n"
只是代码生成输出的一个示例。
#!/bin/bash
f() { cat "$1" | tee "$x" | grep -E "aaa|bbb" >"$y"; }
x=>( a=$(wc -l); echo "Lines in : $a") \
y=>( b=$(wc -l); echo "Lines out: $b") \
f <(printf "aaa\nbbb\nccc\n")
或者没有猫的选项(不太容易理解,但在技术上更正确):
f() { <"$1" tee "$x" | grep -E "aaa|bbb" >"$y"; }
执行时输出为:
$ ./script.sh
Lines out: 2
Lines in : 3
使用后无需清理文件。