xargs の使い方メモ
たまにしか使わないで済んでいるのでいつも使い方を忘れる。
基本
コマンドの出力をパイプで渡すと、各行をコマンドの最後の引数として実行する。
ls | xargs md5 -q
これは次のように展開されたものと同じ。
md5 -q foo md5 -q bar md5 -q baz ...
ただしファイル名にスペースを含んでいると上記の方法ではうまくいかない。この場合、次の節で説明するプレースホルダを使用する。
プレースホルダ
xargs では -I
オプションで引数を展開する場所を指定することができる。-I '{}'
のように指定すると、{}
の場所に引数が展開される。
ls | xargs -I '{}' md5 -q '{}'
これでスペースを含むファイル名もうまく展開される。
md5 -q 'foo' md5 -q 'bar' md5 -q 'foo bar' ...
処理系によっては小文字の -i
オプションで -I '{}'
と同等の動作になるので alias を指定しておくと便利かもしれない。
alias xargs-i='xargs -I "{}"'
拡張子の変更
xargs を使って拡張子を一括置換するにはプレースホルダに加え、 sed を組み合わせるとよい。
find . -name '*.txt' | sed -e 's/[.]txt$//' | xargs -I '{}' mv '{}.txt' '{}.md'
応用例として、 FFmpeg で動画から音声トラックのみ抽出するコマンドを挙げる。
find . -name '*.mp4' | sed -e 's/[.]mp4$//' | xargs -I '{}' ffmpeg -i '{}.mp4' -c:a copy '{}.m4a'
Windows のスクリーンショットを一括で JPEG に変換してリネーム
PowerShell は使わず、WSL の bash や zsh などから使用する。ImageMagick (convert コマンド) がインストールされているものとする。
ls スクリ*.png | \ sed -e 's/スクリーンショット (//' -e 's/)[.]png//' | \ xargs -I '{}' convert 'スクリーンショット ({}).png' 'image-{}.jpg'
一部を切り抜きたい場合はその座標を指定して
# -crop (width)x(height)+(left)+(top) ls スクリ*.png | \ sed -e 's/スクリーンショット (//' -e 's/)[.]png//' | \ xargs -I '{}' convert 'スクリーンショット ({}).png' -crop 1140x641+601+199 'image-{}.jpg'