当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.txt
4、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
pattern[$0]
:这样您就可以将每一整行添加到图案来自第一个输入“a.txt
”的关联数组;$4" "$6" "$8
接下来,将第二个文件中的列 #4、#6 和 #8 与b.txt
该数组中的行进行比较;这些永远不会匹配,因为您正在将整行与特定列值进行比较,而这些值不存在于您的图案大批。因为步骤 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