[英]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 是true
或false
。
更新:在您的示例文件中,匹配词被发现附加到其他字符串的冒号,解决方案本身不会匹配。 您需要将上面的主循环修改为:
{
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.