[英]AWK show until first difference
我希望AWK显示所有内容,直到按照我的标准在两个文件中出现第一个差异为止。
File1行: C000 4C F5 C5 JMP $C5F5 A:00 X:00 Y:00 P:24 SP:FD CYC: 0 SL:241
File2行: JMP $C5F5 0x0000c000 A:00 X:00 Y:00 | SP:fd P:24 N0 V0 B0 D0 I1 Z0 C0
JMP $C5F5 0x0000c000 A:00 X:00 Y:00 | SP:fd P:24 N0 V0 B0 D0 I1 Z0 C0
这两行的结构不同,但这没问题,因为我可以使用正则表达式进行匹配:
awk 'match($0, /P\\:\\([0-9]+)/){print substr($0, RSTART, RLENGTH)}' File1.txt
尽管它在File1
出现在哪一列中,但File1
打印P:24
值。
我想要的是
P:number
值 编辑:输出应如何
文件1 :
A:1 B:2 P:3
A:1 B:2 P:4
A:1 B:2 P:5
文件2 :
A:1 P:3 C:3
A:1 P:4 C:4
A:1 P:55 C:5
输出:
A:1 P:3 C:3
A:1 P:4 C:4
由于第三行有所不同。 我不在乎要输出哪个文件,首先是第二个还是第二个,直到第一个差异:)
$ cat tst.awk
{ match($0,/P:[0-9]+/); key=substr($0,RSTART,RLENGTH) }
NR == FNR { keys[NR]=key; next }
key == keys[FNR] { print; next }
{ exit }
$ awk -f tst.awk file1 file2
A:1 P:3 C:3
A:1 P:4 C:4
如果您有GNU awk,可以使用单词边界使match()更精确:
match($0,/\<P:[0-9]+\>/)
与其他awk相比,这有点棘手,但这是基于将name:value输入保存在数组中的想法的一种替代方案:
$ cat tst.awk
{ for(i=1;i<=NF;++i) if (split($i,t,/:/)==2) a[NR==FNR,FNR,t[1]] = t[2] }
NR==FNR { next }
a[1,FNR,"P"] == a[0,FNR,"P"] { print; next }
{ exit }
$ awk -f tst.awk file1 file2
A:1 P:3 C:3
A:1 P:4 C:4
NR==FNR { for(i=1;i<=NF;++i) if ($i ~ /P:[0-9]+/) { p[NR] = $i; next } }
{ for(i=1;i<=NF;++i) if ($i == p[FNR]) { print; next } }
{ exit }
循环浏览第一个文件中的字段,并使用行号作为键将“ P:...”字段存储到数组中。
在第二个文件中,在数组中查找与相同行号相对应的值,并打印具有匹配值的行。
仅当第二个文件中的行不匹配时,才能到达底部的{ exit }
块。
测试一下:
$ awk -f match.awk file1 file2
A:1 P:3 C:3
A:1 P:4 C:4
基于进行比较之前读取整个第一个文件的效率可能很低,这是一个解决方案,它可以按步读取两个文件。 我省去了很多错误检查,但是我发表了很多评论。 (假设是匹配的对象是在一个字段awk
的领域是什么感觉。)
$ cat uptodiff.awk
# The *last* command line argument is taken as the second file. We pop that off
# the command line in case it's the only command line argument, in which case
# stdin will implicitly be the first file.
BEGIN{f2=ARGV[--ARGC]}
# This function compares each field with the regex in its argument, and
# returns the first one which matches. If there's no match, it returns nothing.
function get(pat, i) {
for(i=1;i<=NF;++i)if($i~pat)return $i
}
# For each line in the first file:
# Get the matching field, read a line from the second file, and get
# its matching field
{ first=get(PAT); getline <f2; second=get(PAT) }
# If the matching fields are different, we're done;
# otherwise print the line (from the second file, since we replaced $0 above)
first != second{exit}1
$ awk -f uptodiff.awk PAT='^P:[[:digit:]]+$' file1 file2
A:1 P:3 C:3
A:1 P:4 C:4
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.