2つのシェル変数をマージしてソートし、重複を削除する方法

2つのシェル変数をマージしてソートし、重複を削除する方法

私のbashスクリプトには、「args1」と「args2」という2つの変数があります。それらのそれぞれには、次のものがあります。

Matching cluster names:
[a-z]+
[a-z]+
...

したがって、「args1」は次のようになります。

Matching cluster names:
dev1ff
dev2ff

そして、「args2」は次のようになります。

Matching cluster names:
dev2ff
dev3ff

これを組み合わせて以下を生成する必要があります。

Matching cluster names:
dev1ff
dev2ff
dev3ff

次の行を使用すると、これに近づくことができます。

echo "$(echo "$args1" | grep -v "^Matching") $(echo "$args2" | grep -v "^Matching")" | sort -u

これにより、次のような結果が得られます。

Matching clusters:
dev1ff
dev2ff dev3ff

実際の名前は重要ではありませんが、問題は、最初のブロックと2番目のブロックの間に改行文字を挿入できないことです。 2つの「$(...)」ブロック間のスペースにいくつかのバリエーションを試しましたが、何も機能しません。

答え1

コマンド置換は末尾の改行を排除するため、2つのコマンド置換の間のスペースを唯一の区切り文字として使用します。結果は次のとおりです。

echoサポートされているすべての場合に-e使用できます。

echo -e "$(...)\n$(...)" | sort -u

途中で改行文字を追加します。ただし、データにバックスラッシュがある場合、echoバックスラッシュも変換されます。これを防ぐには、printf次のように使用できます。

printf "%s\n" "$(...)" "$(...)" | sort -u

(フォーマット文字列は必要なだけ繰り返されるので、2つの引数を使用した場合"%s\n"と同じように機能します。とにかく代わりに%s\n%s\n使用したい場合があります。printfechoなぜprintfがechoより優れているのですか?)


しかし、実際にはコマンドの置換は必要ありません。echo "$(something)"直接実行するのと似ていますsomethingsort -u中かっこを使用して、指示したい2つのコマンドをグループ化できます。

{ echo "$args1" | grep -v "^Matching"; echo "$args2" | grep -v "^Matching"; } | sort -u

あるいは、2つのgrepが同じことをすることに注意してください。 grepを中括弧の外に移動します。

{ echo "$args1"; echo "$args2"; } | grep -v "^Matching" | sort -u

上記の2つのコマンドでは、echosをシェル変数を渡さずにこの出力を生成する他のコマンドに置き換えることができます。

ただし、シェル変数にリストがある場合は、複数のprintfコマンドをグループ化せずに両方のリストを同時に印刷することもできます。

printf "%s\n" "$args1" "$args2" | grep -v "^Matching" | sort -u

関連情報