列と行番号が常に変化するテキスト ファイルがあり、その中のすべての列が $VAR1 または $VAR2 に等しい場合にのみ、txt ファイルから行全体を削除したいと考えています。例:
$VAR1="X"、$VAR2="N" とすると、$VAR1 と $VAR2 が列全体を構成する行をすべて削除します。
私の入力は次のようになります:
hajn 32 ahnnd namm 5 543 asfn F
X X N X X X N X
5739 dw 32eff Sfff 3 asd 3123 1
そしてこれが私が望む出力になります:
hajn 32 ahnnd namm 5 543 asfn F
5739 dw 32eff Sfff 3 asd 3123 1
ループでこれを解決できますが、これを行う強力なワンライナーの方法、できれば awk があるかどうか疑問に思っています。
答え1
$ VAR1=N
$ VAR2=X
$ awk -v a="$VAR1" -v b="$VAR2" '{ for (i=1; i<=NF; ++i) if ($i != a && $i != b) { print; next } }' file
hajn 32 ahnnd namm 5 543 asfn F
5739 dw 32eff Sfff 3 asd 3123 1
ここで、コマンドラインを使用して、値$VAR1
とを$VAR2
短いawk
スクリプトに転送し、その変数a
とを転送します。b
-v
スクリプト内ではawk
、各行のフィールドを反復処理し、いずれかのフィールドがa
と のb
値の両方と異なる場合は、その行全体を出力し、すぐに次の行に進みます。
a
との両方と異なるフィールドがない場合b
、何も起こりません (行は印刷されません)。
答え2
正規表現を正しく選択することで、必要な結果を grep で抽出できます。注: シェル変数には、正規表現の特殊文字として解釈できない、無意味な文字が含まれていると想定します。これが当てはまらない場合は、\Q...\E
コンテキスト内で変数をエンローブできます。
$ grep -P "(^|\s)(?!$VAR1(\s|\$))(?!$VAR2(\s|\$))" inp