
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'
...上記のコードで試した再作業のアイデアは、最初の行の文字を '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|.|.|.|.
望ましい出力:
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
答え1
正しいアイデア - 間違った実装
フィールドを保存する必要がある価値観フィールドでインデックスされた配列位置. の代わりに
a[$i]
、a[i]=$i
次に値を調べる必要がありますインデックス別配列内。そうではない
$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
としてエド・モートンは指摘した明示的なループを awk 組み込み関数に置き換えることで、ソリューションを改善できますsplit
。
awk -F'|' 'BEGIN{OFS=FS} NR==1 {split($0,a)} NR>1 {for(i in a) if( $i == "." ) $i=a[i]}1'