awk:最初の行の同じ列の文字と一致しない場合は、指定された行と列の文字を置き換えます。

awk:最初の行の同じ列の文字と一致しない場合は、指定された行と列の文字を置き換えます。

長年頑張ってきましたが、近づいていませんでした。 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

関連情報