繁体   English   中英

使用 awk 找到或未找到显示匹配

[英]Display match found or not using awk

我有一个场景,我在一个名为 demo.txt 的文件中有三个单词

我的三个字是:苹果、芒果、葡萄

我想编写一个线性命令来检查文件中是否存在所有三个单词然后显示匹配成功,否则显示未找到匹配

如何以一种线性方式处理 awk 命令

下面是我的代码不起作用

awk '{print (/apple/|/mango/|/grapes/ ? "true : match found " : "false : not found ")}' /D/demo.txt

示例文件:demo.txt

abc:apple
b:mango
fgg:grapes
ball , candle 
vik,mani
raj,vilas

除了第一个文件**我还有第二个文件,其中包含以下文本

Azr
hjkds
$$ABC=%wkde**mo
$Bilas=%ram 
xyz
vxbnx
ram 

我想检查是否存在确切的关键字 $$ABC=%wkde**mo $Bilas=%ram

如果找到匹配,则显示消息关键字找到,否则显示关键字未找到

请您尝试以下操作。 如果您的 awk 支持字边界。

awk '
/\<apple\>/{
  app_found=1
}
/\<mango\>/{
  mango_found=1
}
/\<grapes\>/{
  grapes_found=1
}
END{
  if(app_found && mango_found && grapes_found){
    print "All 3 words found."
  }
  else{
    print "All 3 words are NOT present in whole Input_file."
  }
}
' Input_file

编辑后的答案:以下命令已经使用上面提供的输入示例进行了测试,并且可以按需要工作:

awk '
  BEGIN { RS = "§" }
  {print (/apple/ && /mango/&&/grapes/) ? "match found" : "match not found"}
' demo.txt

我使用 char §作为记录分隔符,因为输入中没有这样的 char 并且RS = "\0"不可移植。 如果您觉得输入文件中可能会出现这样的§ ,您可以使用以下便携式解决方案:

awk '
  { i = i $0 } 
  END { print (i ~ /apple/ && i ~ /mango/ && i ~ /grapes/) ? "match found" : "match not found"}
' demo.txt

对于多字符 RS,使用 GNU awk:

awk -v RS='^$' '
    { f = (/apple/ && /mango/ && /grapes/) }
    END { print (f ? "true : match found " : "false : not found "); exit !f }
' /D/demo.txt

或者如果您不想接受部分匹配,则添加单词边界:

awk -v RS='^$' '
    { f = (/\<apple\>/ && /\<mango\>/ && /\<grapes\>/) }
    END { print (f ? "true : match found " : "false : not found "); exit !f }
' /D/demo.txt

您需要在END部分进行打印,而不是在处理输入以正确处理空文件和exit时确保您在匹配成功时设置成功退出状态时的行为与 grep 相同,否则失败。

使用任何 awk 您可以:

awk '
    { rec = rec $0 ORS }
    END {
        $0 = ORS rec
        f = (/[^[:alnum:]_]apple[^[:alnum:]_]/ && /[^[:alnum:]_]mango[^[:alnum:]_]/ && /[^[:alnum:]_]grapes[^[:alnum:]_]/)
        print (f ? "true : match found " : "false : not found ")
        exit !f
    }
' /D/demo.txt

或者如果您不想一次将整个文件读入 memory,那么也可以使用任何 awk:

awk '
    BEGIN { numTgts = split("apple mango pears",words) }
    {
        for (i in words) {
            word = words[i]
            if ( (FS $0 FS) ~ ("[^[:alnum:]_]" word "[^[:alnum:]_]") ) {
                if ( ++numHits == numTgts ) {
                    f = 1
                    exit
                }
                delete words[i]
            }
        }
    }
    END {
        print (f ? "true : match found " : "false : not found ")
        exit !f
    }
' /D/demo.txt

或用于字符串而不是正则表达式比较(以上所有内容都使用):

awk '
    BEGIN {
        numTgts = split("apple mango pears",tmp)
        for (i in tmp) {
            words[tmp[i]]
        }
        FS = "[^[:alnum:]_]+"
    }
    {
        for (i=1; i<=NF; i++) {
            word = $i
            if (word in words) {
                if ( ++numHits == numTgts ) {
                    f = 1
                    exit
                }
                delete words[word]
            }
        }
    }
    END {
        print (f ? "true : match found " : "false : not found ")
        exit !f
    }
' /D/demo.txt

另一个从demo文件中读取单词,将它们散列a hash 中,计算匹配项,如果任何匹配词没有匹配项,则print s false

$ awk 'NR==FNR {           # read and process demo
    split($0,t,/ *, */)    # split by comma and spaces, if any to a temp array
    for(i in t)            # make another array with match words as keys
        a[t[i]]
    next
}
{
    for(i=1;i<=NF;i++)     # iterate all space separated words in the file
        if($i in a)
            a[$i]++        # count match words in  it
}
END {                      # in the end
    for(i in a)
        if(!a[i]) {        # if there was a match word that had no matches
            print "false"  # print false
            exit           # and exit
        }
    print "true"           # else all match words matched in the file
}' demo file

Output 是truefalse

更新:在您的示例文件中,匹配词被发现附加到其他字符串的冒号,解决方案本身不会匹配。 您需要将上面的主循环修改为:

{
    n=split($0,t,/[^a-zA-Z]+/) # split by all non-alphabetical chars
    for(i=1;i<=n;i++)          # iterate all words in the array t
        if(t[i] in a)
            a[t[i]]++          # count match words in it
}

它将按所有非字母字符( [^a-zA-Z] )分割行,并将这些子字符串视为单词。 修改该正则表达式以满足您的需求。

Perl 可以得心应手

$ perl -0777 -ne  ' if( /apple/ && /mango/ && /grapes/ ) { print "Found\n" } else { print "not found\n" }  ' demo.txt
Found
$ 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM