如何在Bash脚本中仅获取模式的第一个匹配项

huangapple go评论65阅读模式
英文:

How to get only the first occurrence of the pattern in bash script

问题

:name1
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
:name3
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
:name4
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
英文:

Hi All can you please help me I am trying to get the following output so basically I have 2 input files and we need only the common :names from both the input files along with there the lines below them the .name/of/file lines.

Till now I have tried:

awk 'FNR==NR { a[$1]; next }NF<=1   { flag=0   } $1 in a { flag=1   }flag' file1 file2

Output:

:name1
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
:name3
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
:name1
    ./name/of/file [logfile] [ error in file coming since Day : 40]
    ./name/of/file [logfile] [ error in file coming since Day : 40 ]
:name4
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]

:name4
./name/of/file [logfile] [ error in file coming since Day : 10 ]
./name/of/file [logfile] [ error in file coming since Day : 10 ]
./name/of/file [logfile] [ error in file coming since Day : 10 ]
./name/of/file [logfile] [ error in file coming since Day : 10 ]

But its printing all the occrance of :name1 and :name4 we only need the first occurrence of :name1 and :name4 from input file 1

Input file1:

:name1
./name/of/file [logfile] [ error in file coming since Day : 1 ]
./name/of/file [logfile] [ error in file coming since Day : 1 ]

:name2
./name/of/file [logfile] [ error in file coming since Day : 1 ]

:name3
./name/of/file [logfile] [ error in file coming since Day : 24 ]
./name/of/file [logfile] [ error in file coming since Day : 24 ]

 :name1
./name/of/file [logfile] [ error in file coming since Day : 40]
./name/of/file [logfile] [ error in file coming since Day : 40 ]

:name4
./name/of/file [logfile] [ error in file coming since Day : 3 ]
./name/of/file [logfile] [ error in file coming since Day : 3 ]
./name/of/file [logfile] [ error in file coming since Day : 3 ]
./name/of/file [logfile] [ error in file coming since Day : 3 ]

:name5
./name/of/file [logfile] [ error in file coming since Day : 6 ]
./name/of/file [logfile] [ error in file coming since Day : 6 ]

:name4
./name/of/file [logfile] [ error in file coming since Day : 10 ]
./name/of/file [logfile] [ error in file coming since Day : 10 ]
./name/of/file [logfile] [ error in file coming since Day : 10 ]
./name/of/file [logfile] [ error in file coming since Day : 10 ]  

Input file2:

:name1
:name3
:name4

Required Outputfile:

:name1
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
:name3
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
:name4
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]

答案1

得分: 1

由于“出现”是基于名称在a[]数组中存在作为索引,从数组中删除该条目应该禁用任何进一步的“出现”。

我们可以通过在当前的awk代码中添加delete来实现这个删除:

awk '
FNR==NR { a[$1]; next }
NF<=1   { flag=0 }
$1 in a { flag=1; delete a[$1] }
flag
' file2 file1

这将生成:

:name1
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
:name3
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
:name4
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]

如果需要将日志文件行缩进(例如,如问题中的4个空格),一种方法是:

awk '
FNR==NR { a[$1]; next }
NF<=1   { flag=0 }
$1 in a { print; flag=1; delete a[$1]; next }
flag    { printf "    %s\n",$0 }
' file2 file1

这将生成:

:name1
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
:name3
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
:name4
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
英文:

Since an 'occurrence' is based on the name existing as an index in the a[] array, removal of that entry from the array should disable any further 'occurrences'.

We can accomplish this removal by adding a delete to the current awk code:

awk &#39;
FNR==NR { a[$1]; next          }
NF&lt;=1   { flag=0               }      # clear flag if zero or one non-white-space fields is present in the current line
$1 in a { flag=1; delete a[$1] }      # set flag if 1st field is an index in the a[] array; delete entry from array to insure no more occurrences of this name ($1)
flag                                  # if flag == 1 then print current line to stdout
&#39; file2 file1

This generates:

:name1
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
:name3
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
:name4
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]

If the logfile lines need to be indented (eg, 4 spaces as in the question), one idea:

awk &#39;
FNR==NR { a[$1]; next }
NF&lt;=1   { flag=0 }
$1 in a { print; flag=1; delete a[$1]; next }
flag    { printf &quot;    %s\n&quot;,$0 }
&#39; file2 file1

This generates:

:name1
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
    ./name/of/file [logfile] [ error in file coming since Day : 1 ]
:name3
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
    ./name/of/file [logfile] [ error in file coming since Day : 24 ]
:name4
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]
    ./name/of/file [logfile] [ error in file coming since Day : 3 ]

huangapple
  • 本文由 发表于 2023年2月10日 04:20:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75404023.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定