Edited at

Bashのfor文をワンライナーへ書き換える方法

More than 1 year has passed since last update.

xargsコマンドを用いて、Bashのfor文をワンライナーへ書き換える方法についてまとめてみます。


xargsコマンドとは

標準入力からリストを読み込み、それをコマンドの引数として展開・実行するコマンドです。


改行区切りのリストを処理する場合


基本的な書き換え

以下のような処理があったとします。

for f in `ls`

do
echo "Output:" ${f}
done

これをxargsコマンドを用いて書き換えると、以下のようになります。

ls | xargs -r -L 1 echo "Output:"

ここで、-Lオプションはリストが改行区切りであるという前提の元、コマンドに展開する引数の個数の最大値を指定しています。

さらに、-rオプションを指定することで、リストが空の場合にコマンドを実行しないようにしています。


引数を任意の位置に展開する場合


展開する引数が1個の場合

以下のように記述することで、引数を任意の位置に展開することができます。

ls | xargs -r -I @ echo "Output:" @

ここで、-Iオプションは引数を表す文字列を指定しており、このオプションが指定された場合、自動的に-L 1も指定されたことになります。


展開する引数が2個以上の場合や展開する引数内で変数内置換を用いる場合

以下のように記述することで、引数を任意の位置に展開することができます。

ls | xargs -r -L 2 bash -c 'echo "Output:" ${0} ${1}'

この場合、${0}, ${1} (${0}${引数の個数の最大値-1}) は引数の位置を表しており、bashコマンドを間に挟んでコマンドを実行しています。


改行区切りではないリストを処理する場合


基本的な書き換え

以下のような処理があったとします。

for s in "aaa" "iii"

do
echo "Output:" ${s}
done

これをxargsコマンドを用いて書き換えると、以下のようになります。

echo "aaa" "iii" | xargs -r -n 1 echo "Output:"

ここで、-nオプションはリストが改行区切りではないという前提の元、コマンドに展開する引数の個数の最大値を指定しています。

さらに、-rオプションを指定することで、リストが空の場合にコマンドを実行しないようにしています。


引数を任意の位置に展開する場合

以下のように記述することで、引数を任意の位置に展開することができます。

echo "aaa" "iii" "uuu" "eee" | xargs -r -n 2 bash -c 'echo "Output:" ${0} ${1}'

この場合、${0}, ${1} (${0}${引数の個数の最大値-1}) は引数の位置を表しており、bashコマンドを間に挟んでコマンドを実行しています。


並列化

以下のようにxargsコマンドを用いると、for文で記述した場合には不可能であった並列化が可能になります。

echo "aaa" "iii" | xargs -r -n 1 -P 2 echo "Output:"

ここで、-Pオプションはプロセス数の最大値を指定しています。


参考文献