列出文件名,不包括使用grep的两个字符串

时间:2013-09-24 09:08:02

标签: string bash grep

我有一个文件夹,我有很多WSDL。我想找出哪些WSDL不包含字符串'binding style =“document”''binding style =“rpc”'。 我尝试过跟随grep命令,但它没有工作,我猜是因为它检查OR而不是AND。

grep -Ev 'binding style=\"rpc\"|binding style=\"document\"' -l folder/* | cut -f2 -d'/'

4 个答案:

答案 0 :(得分:4)

您可以使用awk代替grep,因为它可以让您将正则表达式匹配与逻辑运算符结合使用:

打印两个匹配的行:

$ awk '$0~s1 && $0~s2' s1='binding style="rpc"' s2='binding style="document"'  

打印至少有一个匹配的行:

$ awk '$0~s1 || $0~s2' s1='binding style="rpc"' s2='binding style="document"'  

打印不匹配的行

$ awk '!($0~s1 || $0~s2)' s1='binding style="rpc"' s2='binding style="document"'

要仅打印文件名,您可以使用GNU awk对包含两个匹配项的文件执行以下操作:

$ awk '$0~s1 && $0~s2{print FILENAME;nextfile}'

包含至少一个匹配项的文件:

$ awk '$0~s1 || $0~s2{print FILENAME;nextfile}'

包含任何行匹配的文件:

$ awk '$0~s1{f1=1} $0~s2{f2=1}ENDFILE{if (f1&&f2) print FILENAME;f1=f2=0}'

不包含匹配项的文件:

$ awk '$0~s1{f1=1} $0~s2{f2=1}ENDFILE{if (!(f1||f2)) print FILENAME;f1=f2=0}'

你仍然需要添加s1s2的定义我只是为了保持线条的简洁性以便于阅读。我选择在脚本之后定义s1s2的原因是因为字符串包含双引号并且这样做可以避免任何讨厌的转义。如果您的匹配没有引号,您可以这么做:

$ awk '/foo/ && /bar/{print FILENAME;nextfile}' folder/* | basename

对于字符串foobar等...

答案 1 :(得分:1)

使用单引号时,您不必引用"

grep -vE 'binding style="rp"|binding style="document"' -l folder/* | cut -f2 -d'/'

要让文件不包含这些模式:

awk 'BEGIN {
    for (i = 1; i < ARGC; ++i) {
        m = 0
        file = ARGV[i]
        while ((getline line < file) > 0) {
            if (line ~ /binding style="rp"|binding style="document"/) {
                m = 1
                break
            }
        }
        close(file)
        if (m == 0) {
            print file
        }
    }
    exit
}' folder/* | cut -f2 -d'/'

单行命令:

awk 'BEGIN{for(i=1;i<ARGC;++i){m=0;file=ARGV[i];while((getline line<file)>0){if(line ~ /binding style="rp"|binding style="document"/){m=1;break}}close(file);if(m==0){print file}}exit}' folder/* | cut -f2 -d'/'

要查看文件名:

awk 'BEGIN {
    for (i = 1; i < ARGC; ++i) {
        m = 0
        file = ARGV[i]
        while ((getline line < file) > 0) {
            if (line ~ /binding style="rp"|binding style="document"/) {
                m = 1
                break
            }
        }
        close(file)
        if (m == 0) {
            sub(/.*\//, "", file)
            print file
        }
    }
    exit
}' folder/*

您不再需要使用剪切。

单行命令:

awk 'BEGIN{for(i=1;i<ARGC;++i){m=0;file=ARGV[i];while((getline line<file)>0){if(line ~ /binding style="rp"|binding style="document"/){m=1;break}}close(file);if(m==0){sub(/.*\//,"",file);print file}}exit}' folder/*

答案 2 :(得分:1)

这将打印所有不包含字符串binding style="rp"binding style="document"

的文件的文件名
perl -le 'for $f (@ARGV) { $p=0;open($fh,$f); while(<$fh>) { $p++ if (/binding style="rp"|binding style="document"/); } print $f unless $p;}' *

我假设你想要文件名

答案 3 :(得分:0)

ls -1 folder/*|perl -lne 'print unless(/binding style=\"(rpc|document)\"/)' |cut -f2 -d'/'