1

我有一个文件夹,里面有一堆 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

4 回答 4

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...

于 2013-09-24T09:13:41.610 回答
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/*

您不再需要使用 cut。

单行命令:

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/*
于 2013-09-24T09:11:47.190 回答
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;}' *

我假设你想要文件名

于 2013-09-24T09:22:50.500 回答
0
ls -1 folder/*|perl -lne 'print unless(/binding style=\"(rpc|document)\"/)' |cut -f2 -d'/'
于 2013-09-24T09:11:48.213 回答