繁体   English   中英

AWK表演直到第一个区别

[英]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
  • 当P值不同时停止输出

编辑:输出应如何

文件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.

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