カンマ区切りリストを次のコマンドの引数として渡す方法

カンマ区切りリストを次のコマンドの引数として渡す方法

s1たとえば、「、」で区切られた数字のリストを出力するスクリプトがあります1,2,3,4。今度はこの数値をs2スクリプトに引数として与え、s2が各数値に対して実行され、結果を別々の行に出力するようにしたいと思います。たとえば、s2が数値に2を掛けた場合、私が探す結果は次のようになります。

2
4
6
8

私が今やっていることは:

s1 | xargs -d "," | xargs -n1 s2

でも、こんなことをするなんて私がバカになったらしい!だから私の質問は次のようになります

正しいアプローチは何ですか?

私の解決策の問題は、xargsを2回呼び出して入力を2回繰り返すことです。もちろん私の意見では、パフォーマンスの観点から見ると、理に合わない!答えはxargs -d "," -n1良いようですが、一度だけ繰り返されるかどうかはわかりません。これが実際に本当なら、答えでこれを確認していただければ受け入れます。しかし、Perlはまだ2回繰り返され、Perlが多くのシステムに存在しない可能性があるため、Perlを使用したくありません。

答え1

この方法も同様にうまく機能します。

s1 | xargs -d "," -n1 s2

テストケース:

printf 1,2,3,4 | xargs -d ',' -n1 echo

結果:

1
2
3
4

リストが出力されて改行文字が続く場合は、s1それらを削除する必要があります。それ以外の場合、最後の呼び出しは次の4\n代わりに使用されます4

s1 | tr -d '\n' | xargs -d , -n1 s2

答え2

複数のパラメータを許可できる場合は、s2次のことができます。

(IFS=,; ./s2 $(./s1))

サブシェル内でIFSをカンマで一時的にオーバーライドするため、カンマで区切られたs2出力が表示されます。s1サブシェルは、古い値を保存またはリセットせずにIFSを変更する簡単な方法です。

この回答の以前のバージョンは、無効なIFS設定が原因で結果が破損している可能性があります。ありがとうイルカチョ~のため私の間違いを指摘してください。

出力を手動でループして個別に供給するには、s2IFSを保存してリセットする方法について説明します。

oIFS="$IFS"
IFS=,
for output in $(./s1); do ./s2 "$output"; done
IFS="$oIFS"

または、以前のようにサブシェルでIFSビットを実行します。

(
IFS=,
for output in $(./s1); do ./s2 "$output"; done
)

答え3

この試み:

s1 | perl -pe 's/,/\n/g' | xargs -n1 s2

関連情報