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
オプションはプロセス数の最大値を指定しています。