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設定が原因で結果が破損している可能性があります。ありがとうイルカチョ~のため私の間違いを指摘してください。。
出力を手動でループして個別に供給するには、s2
IFSを保存してリセットする方法について説明します。
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