私は2つの文字列を持っています:
l1='a1 a2 b1 b2 c1 c2'
l2='a1 b3 c1'
そして、 string の各要素が にl2
存在するかどうかを確認しl1
、 から削除しl1
ます。
for
ループなしでそれを行うことは可能ですか?
あなたはこれを行うことができます:
l1=$(comm -23 <(echo "$l1" | tr ' ' '\n' | sort) <(echo "$l2" | tr ' ' '\n' | sort) | tr '\n' ' ')
はcomm
ラインを比較し、最初の入力に固有のライン、2 番目の入力に固有のライン、および両方に共通のラインを出力します。この-23
オプションは、2 番目の 2 セットの出力を抑制するため、最初の入力に固有の行のみを報告します。
入力はソートされた行である必要があるため、最初に変数を にパイプしてtr
各単語をそれぞれの行に配置し、次にそれsort
をソートします。ファイル名が必要な場所でコマンドを使用できるようにする、プロセス置換<(...)
と呼ばれる一般的なシェル拡張です。たとえば、およびで利用できます(どのシェルがそれを持っているかをリストした表については、こちらを参照してください)。bash
zsh
最後に、tr
もう一度使用して、改行をスペースに戻します。
プロセス置換がない場合は、名前付きパイプでエミュレートできます。
mkfifo p1
echo "$l1" | tr ' ' '\n' | sort > p1 &
mkfifo p2
echo "$l2" | tr ' ' '\n' | sort > p2 &
l1=$(comm p1 p2 | tr '\n' ' ')
rm p1 p2