bashスクリプトでawkを使用してif-then-elseステートメントを記述しています。
私がやりたいのは、特定の文字列(rsまたはchr)と一致しない列1の値を持つ行を識別し、それらの識別された行の列1の値にプレフィックス(chr)を追加することです。文字列が一致するすべての行は、そのまま印刷されます。追加はありません。
これまでのコード行は次のとおりです。
awk "{if (! ($1 ~ /rs/ || $1 ~ /chr/)) {($1 == "chr"$1); print $0}}; else {print $0}" filename > newfilename
Iこのコードで構文エラーメッセージを受信し続けます。
識別と追加を自分で正常に実行できますが、それらを1つのコマンドに組み合わせるのに問題があります。
コメント
回答
コードは、見やすくするために展開されています:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { ($1 == "chr"$1); print $0} }; else { print $0 } " filename > newfilename
これには、頭に浮かぶ問題がいくつかあります
- 割り当てではなく、等式比較を使用して試してみます
chr
プレフィックスを追加します - 割り当てを括弧で囲みます
- 無関係な最初の
-
else
の部分の前にセミコロンがあってはなりません - 最後の終わりがありません
}
コードの後
これは修正されたバージョンですが、まだ拡張されています:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1; print $0 } else { print $0 } } " filename > newfilename
そして、繰り返されるprint $0
を条件の外に移動するための簡単な最適化を見ることができます:
awk " { if (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } print $0 } " filename > newfilename
これは基本的に単純な「条件→修正」であり、実際にはawk
の標準構造を使用してこれをさらに単純化できます。ここに2つのawk
ステートメントがあり、入力ファイルのすべての行に対して順番に処理されます。最初の行は、必要に応じて"chr"
のプレフィックスを付けます。 2番目はすべての行を印刷します。
awk " (! ($1 ~ /rs/ || $1 ~ /chr/) ) { $1 = "chr" $1 } 1 " filename > newfilename
これはawk
なので、1行にまとめることもできます。 、読みやすさには少し問題がありますが
awk "(! ($1 ~ /rs|chr/) ) { $1 = "chr" $1 } 1" filename > newfilename
回答
この行を使用すると完全に機能する:
awk "!($1 ~ /rs/ || /chr/) {$1="chr"$1}1"
コメント
-
($1 ~ /rs/ || /chr/)
"rs"
の場合は$1
と一致しますが、"chr"
と一致します。
。 ($1 ~ /rs/ || $1 ~ /chr/)
または($1 ~ /rs|chr/)
のいずれかである必要があります
'{ if ( this is given) { do this } else { do that } }'