行内のすべての列が $VAR1 または $VAR2 の場合のみ行全体を削除します。

行内のすべての列が $VAR1 または $VAR2 の場合のみ行全体を削除します。

列と行番号が常に変化するテキスト ファイルがあり、その中のすべての列が $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

関連情報