英文:
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 '
FNR==NR { a[$1]; next }
NF<=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
' 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 '
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
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 ]
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论