長年頑張ってきましたが、近づいていませんでした。 awkを使用すると、すべての列の> 1であるすべての行のすべての '*'を '-'に置き換えることはどうですか?ただし、行1の対応する列が「*」でない場合にのみ可能ですか?
入力例:
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|*|*|f|g|*|*|*|*|g|c|a|*|A|*
*|s|*|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|*|g|*|T|*|C|g|c|a|a|A|T
出力例
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T
答え1
ヘッダー行で「*」以外のすべての項目を検索する必要があります。
「none」列は*
配列に保存できますa[]
。
次のすべての行に対して、次の行にのみ存在します。a[]
可能変更が必要です。
これは次のように実装できます。
awk -F'|' 'BEGIN{OFS=FS}
NR==1 {
for(i=1;i<=NF;i++) if( $i != "*" ) a[i]
}
NR>1 {
for(i in a) if( $i == "*" ) $i="-"
}
1
' file
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T
これは必要な最小限の変更を実装します。最速でなければなりません。
答え2
1つの可能なアプローチ(おそらく最善ではないでしょう)
awk -F'|' '
BEGIN{OFS=FS}
NR==1 {
for(i=1;i<=NF;i++) if($i=="*") a[i]
}
{
for(i=1;i<=NF;i++) if($i=="*" && !(i in a)) $i="-"
}
1
' file
a|s|d|f|g|*|A|*|*|g|c|a|*|A|*
a|-|-|f|g|*|-|*|*|g|c|a|*|A|*
-|s|-|f|g|*|a|t|*|g|c|a|*|A|*
a|s|d|-|g|*|T|*|C|g|c|a|a|A|T