NR==FNR,当两个文件匹配时需要修改

NR==FNR,当两个文件匹配时需要修改

当b.txt文件的一行匹配时,我想修改入口处的a.txt行(即用b.txt文件的$2替换$1),但它不起作用。

输入

*a.txt*
201 A B 580 D1
208 A B 581 D2
214 A B 582 D3

*b.txt*
10 101 E1 A Z1 B Z2 580 Z3
11 104 E2 C Z1 B Z2 581 Z3
12 107 E3 A Z1 B Z2 581 Z3
14 111 E3 B Z1 S Z2 582 Z3
15 116 E2 A Z1 B Z2 582 Z3

输出

*c.txt*
101 A B 580 D1
107 A B 581 D2
116 A B 582 D3
10 101 E1 A Z1 B Z2 580 Z3
12 107 E3 A Z1 B Z2 581 Z3
15 116 E2 A Z1 B Z2 582 Z3

我的代码

awk 'NR==FNR{pattern[$0]; next} {if($4" "$6" "$8 in pattern) {print $0; gsub(pattern[$1],$2); print pattern[$0]}}' a.txt b.txt >> c.txt

我的代码有什么问题,没有结果?

答案1

回答修改后的问题:

awk 'NR==FNR {$1=""; afile[$2, $3, $4]=$0; next; }
    (($4, $6, $8) in afile){ print $2 afile[$4, $6, $8]; }1' a.txt b.txt

对于问题的旧版本有效:

$ awk 'NR==FNR { afile[$2, $3, $4]=1; next; } 
       (($4, $6, $8) in afile){ print $2, $4 ,$6 , $8; }1' a.txt b.txt >c.txt

a.txt仅将第 2、3 和 4 列读入名为 的关联数组中afile;然后比较第二个文件中b.txt4、6 和 8 上的相应列,如果在数组中看到,则$1完整打印第二个文件中所需的列以及其余的 4、6 和 8 列;否则默认打印1不匹配的行。

结果c.txt

101 A B 580
10 101 E1 A Z1 B Z2 580 Z3
11 104 E2 C Z1 B Z2 581 Z3
107 A B 581
12 107 E3 A Z1 B Z2 581 Z3
14 111 E3 B Z1 S Z2 582 Z3
116 A B 582
15 116 E2 A Z1 B Z2 582 Z3

但是你的代码有问题:

awk 'NR==FNR{pattern[$0]; next} {if($4" "$6" "$8 in pattern) {print $0; gsub(pattern[$1],$2); print pattern[$0]}}' a.txt b.txt >> c.txt
  1. pattern[$0]:这样您就可以将每一整行添加到图案来自第一个输入“ a.txt”的关联数组;

  2. $4" "$6" "$8接下来,将第二个文件中的列 #4、#6 和 #8 与b.txt该数组中的行进行比较;这些永远不会匹配,因为您正在将整行与特定列值进行比较,而这些值不存在于您的图案大批。

  3. 因为步骤 2 永远不会满足 if 语句的内部块也永远不会运行;我不会解释你用它做什么。

答案2

首先,我们构建一个由 8 个块/字段组成的正则表达式,并记住偶数个字段。正则表达式基于具有扩展正则表达式模式的 gnu sed。

$ re='\S+ (\S+)'
$ for i in 1 2; do re="$re $re"; done
$ sed -En "/\n/{P;d;}
    s/\s+/ /g;s/^ | \$//g
    /(\S+ ){6}/bb
    s/^\S+ //;H;d
    :b;G
    /^$re .*\n(\2 \3 \4 \S+)/{
      s//\1 \5\n&/;P;D
    }
" a.txt b.txt \
| sed -e 'n;H;2h;$!d;g'

输出:

101 A B 580 D1
107 A B 581 D2
116 A B 582 D3
10 101 E1 A Z1 B Z2 580 Z3
12 107 E3 A Z1 B Z2 581 Z3
15 116 E2 A Z1 B Z2 582 Z3

相关内容