JP / EN

広告

xargsの使い方:ファイルなどへの反復操作を簡単に

タグ:linux

概要


複数のファイルをまとめて処理したり、ファイルの各行を処理するのをコマンド一つで済ませたいことがたまにある。
もちろんシェルスクリプトにもfor文があるのでそれを使う手もあるが、for文をコマンド内で1行にまとめようと思うとなかなか骨が折れる。
そんなときのためにあるのがxargs(エックスアーグズ)コマンドだ。 xargsは引数を各行に分解して、それぞれに別個にコマンド適用をしてくれるコマンドだ。

主要なオプション:
  • -a [file]: 標準入力でなくファイルから読み込む
  • -d [char]: 入力の区切り文字を指定、デフォルトは改行
  • -I [string]: プレースホルダを指定、この文字列を入力で置き換えることでコマンドを組み上げてくれる。慣例的には"{}"にする。
  • -t: 組み上げたコマンドを実行前に出力(注意:実行もする)デバッグに便利


基本の使い方

    # 実験用ファイルをあらかじめ3つ作っておいた
    $ ls
    aaa  bbb  ccc
    $ cat aaa
    a
    $ cat bbb
    b
    $ cat ccc
    c

    # ファイルをまとめてcat
    $ ls | xargs -t -I{} cat {} ;
    cat aaa
    a
    cat bbb
    b
    cat ccc
    c

    $ ls | xargs -I{} cat {} ;
    a
    b
    c
  


応用例


変更日時順にtop100のファイルをコピー
  $ ls -t | head -n 100 | xargs -I{} cp {}  bak/{}
  


sedと組み合わせてファイル名もいじる;sh -cによるコマンド実行で、xargsが成形したコマンドを走らせればよい。
最初はバッククォートでできると思ったのだが、評価順序の問題でうまくいかなかった。
    $ ls
    ccc  ddd.d
    $ ls | xargs -t -I{} sh -c 'echo {} | sed "s/\./_/"'
    sh -c echo ccc | sed "s/\./_/"
    ccc
    sh -c echo ddd.d | sed "s/\./_/"
    ddd_d

    # 失敗例:バッククォートはxargs実行前に評価されてしまう
    $ ls | xargs -t -I{} `echo {} | sed "s/\./_/"`
    {}
    xargs: {}: Permission denied

    # 失敗例:evalは権限上実行できないようになっているようだ
    $ ls | xargs -t -I{} eval echo {} | sed "s/\./_/"
    eval echo aaa
    xargs: eval: Permission denied
  


余談


xargsの名前は"eXecute ARGumentS"から来ていると思われる。manでの説明が xargs - build and execute command lines from standard input となっているからだ。


このエントリーをはてなブックマークに追加

https://wonderhorn.net/