替换所有行中的特定字符匹配,使用第一行作为参考

Gil*_*les 2 linux awk text-processing

H、我想替换所有行中的特定字符匹配(.),以第一行作为参考

我试图重新散列一个答案,但我遇到了一个不同的问题:

awk -F'|' 'BEGIN{OFS=FS} NR==1 {for(i=1;i<=NF;i++) a[$i] } NR>1 {for(i in a) if( $i == "\." ) $i="a"}1'
Run Code Online (Sandbox Code Playgroud)

...我在上面的代码中尝试重新工作的想法是将第一行字符存储在'a'中,然后在看到'.'时 在行> 1 中更改 '.' 到存储在'a'中的相应列字符。但它不起作用。

输入:

A|N|G|O|T|T|T|P|G|C|Q|A|R|A|S|G|U|V|T|T
.|C|G|A|T|T|.|.|G|C|.|.|.|A|C|R|C|.|T|T
A|.|.|.|N|.|T|T|N|.|.|A|C|.|.|R|.|.|.|.
Run Code Online (Sandbox Code Playgroud)

期望输出:

A|N|G|O|T|T|T|P|G|C|Q|A|R|A|S|G|U|V|T|T
A|C|G|A|T|T|T|P|G|C|Q|A|R|A|C|R|C|V|T|T
A|N|G|O|N|T|T|T|N|C|Q|A|C|A|S|R|U|V|T|T
Run Code Online (Sandbox Code Playgroud)

ste*_*ver 6

正确的想法 - 错误的实施

  1. 您需要将字段存储在由字段position索引的数组中。所以,而不是a[$i],让a[i]=$i

  2. 然后您需要数组中的索引查找值。所以,不$i="a"$i=a[i]

顺便$i == "\."说一句,不是正则表达式测试,所以你不需要逃避.

$ awk -F'|' 'BEGIN{OFS=FS} NR==1 {for(i=1;i<=NF;i++) a[i]=$i } NR>1 {for(i in a) if( $i == "." ) $i=a[i]}1' file
A|N|G|O|T|T|T|P|G|C|Q|A|R|A|S|G|U|V|T|T
A|C|G|A|T|T|T|P|G|C|Q|A|R|A|C|R|C|V|T|T
A|N|G|O|N|T|T|T|N|C|Q|A|C|A|S|R|U|V|T|T
Run Code Online (Sandbox Code Playgroud)

正如Ed Morton 指出的那样,您可以通过使用 awk 内置split函数替换显式循环来改进解决方案:

awk -F'|' 'BEGIN{OFS=FS} NR==1 {split($0,a)} NR>1 {for(i in a) if( $i == "." ) $i=a[i]}1'
Run Code Online (Sandbox Code Playgroud)