Bash:grep为所有行返回true

时间:2017-03-26 02:06:14

标签: bash grep

我有几行(我不知道有多少行)。我通过管道将它们发送到grep。我需要找出grep是否选择了所有行。然后我需要写好(如果他们都被选中)或不好。我怎么能这样做?

4 个答案:

答案 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

使用后无需清理文件。