web-dev-qa-db-ja.com

次のコマンドの引数としてコンマ区切りのリストを与える方法

スクリプトがあります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いい感じですが、1回だけ繰り返すかどうかはわかりません。一致する場合は、回答でそれを確認してください。同意し​​ます。ちなみに、Perlは2回繰り返しているため、Perlを使用したくありません。Perlは多くのシステムに存在しない可能性があります。

9

これも同様に機能するはずです。

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
18
George Udosen

s2が複数の引数を受け入れることができる場合は、次のようにすることができます。

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

これは、IFSを一時的にコンマにオーバーライドして、すべてサブシェルに入れるため、s2s1の出力をコンマで分割して表示します。サブシェルは、以前の値を保存したりリセットしたりせずにIFSを変更する簡単な方法です。

この回答の以前のバージョンは正しくありませんでした。おそらく残りのIFS設定が原因で、結果が破損しています。 ilkkach のおかげで 私の間違いを指摘

出力を手動でループして個別に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
)
6
Jeff Schaller

これを試して:

s1 | Perl -pe 's/,/\n/g' | xargs -n1 s2
1
Gilles Quenot