01 / 08
パイプでは渡せない相手がいる
ここまでパイプで何でもつなげてきたけれど、うまくいかない相手がいるんだ。
find . -name '*.tmp' | rm # ✗ 何も消えない理由は rm の作りにあるよ。rm は入口(標準入力)を読まないんだ。消すものは引数で受け取る決まりなんだよ。
rm furui/a.tmp furui/b.tmp # ◯ 引数で渡す流れてきた文字を、引数の形に変えて渡す。それをするのが xargs だよ。
つなぐ
INPUT · スライド
01 / 08
ここまでパイプで何でもつなげてきたけれど、うまくいかない相手がいるんだ。
find . -name '*.tmp' | rm # ✗ 何も消えない理由は rm の作りにあるよ。rm は入口(標準入力)を読まないんだ。消すものは引数で受け取る決まりなんだよ。
rm furui/a.tmp furui/b.tmp # ◯ 引数で渡す流れてきた文字を、引数の形に変えて渡す。それをするのが xargs だよ。
02 / 08
ここで道具を2種類に分けて覚えよう。
入口を読む道具(パイプでそのまま渡せる)
grep sort wc head tail uniq tr less tee引数しか受け取らない道具(xargs が要る)
rm cp mv mkdir touch chmod echo見分け方があるよ。ファイルを操作する道具は引数側、中身を加工する道具は入口側だよ。
名前を扱う仕事(消す・作る・動かす)には xargs。中身を扱う仕事(探す・数える・並べる)にはパイプだけ。そう覚えるといいよ。
03 / 08
xargs の仕事はひとつxargs がやることは1つだけだよ。入口から受け取った文字を、うしろに書いたコマンドの引数として並べる。
~ $ echo a.txt b.txt | xargs touch(= touch a.txt b.txt を実行した)改行も空白も区切りとして扱うので、find や ls の出力(1行1件)をそのまま渡せるよ。
find . -name '*.tmp' | xargs rm見つけたものを全部消す、というのがこれで書けるんだ。
~ $ find . -name '*.tmp'./furui/a.tmp./furui/b.tmp~ $ find . -name '*.tmp' | xargs rm04 / 08
xargs は既定ではできるだけまとめて渡すよ。100個あっても1回のコマンドで渡そうとするんだ(そのほうが速いからね)。
1つずつにしたいときは -n1 だよ。
~ $ echo a b c | xargs echoa b c ← 1回で渡した~ $ echo a b c | xargs -n1 echoabc ← 3回に分けた-n2 なら2つずつ。渡す個数を決められるんだ。
05 / 08
-I{} で置き場所を決めるxargs はふつううしろに付け足す形で渡すよ。でも「真ん中に入れたい」ことがあるんだ。
cp ファイル ファイル.bakこれは同じ名前を2か所に書きたいよね。そのときは -I{} を使うよ。
ls *.txt | xargs -I{} cp {} {}.bak{} が受け取った1行に置き換わるんだ。-I を使うと自動で1行ずつになるよ(-n1 と同じ扱い)。
{} という書き方は find -exec と同じだね。覚えることが1つ減るよ。
06 / 08
-t で何を実行するか見るxargs は怖い道具だよ。rm と組み合わせるとまとめて消えるからね。
だから打つ前に確かめる方法を覚えよう。-t を付けると、実行するコマンドを見せてから動くんだ。
find . -name '*.tmp' | xargs -t rmrm ./furui/a.tmp ./furui/b.tmp ← これを実行するよ、という表示もっと安全なのは、まず xargs を付けずに find だけ打つことだよ。出てきた一覧が消したいものだけなら、そこで初めて | xargs rm を足す。
確かめてから消す。この順番は一生使う習慣になるよ。
07 / 08
xargs には弱点があるよ。空白を区切りとして見るので、名前に空白があると壊れるんだ。
~ $ lssp ace.txt~ $ ls | xargs wc -cwc: sp: No such file or directorywc: ace.txt: No such file or directorysp ace.txt が2つの名前だと思われてしまったね。
直し方は決まっているよ。find に -print0、xargs に -0 を付けるんだ。区切りを空白ではなく見えない文字(NUL)にする指示だよ。
find . -name '*.txt' -print0 | xargs -0 wc -cおまじないに見えるけれど、空白入りの名前を扱うときの決まり文句として覚えておいて。
08 / 08
furui の中に .tmp ファイルが2つ入っているよ。消す練習に使うよ(この環境のホームは問題ごとに作り直されるので、安心して消してね)。
iremono.txt には haru・natsu・aki と書いてあるよ。これを使って入れ物をまとめて作る練習をするよ。
xargs は覚えることが少ないけれど、組み合わせると効き目が大きい道具だよ。「探して、まとめて処理する」がこれでできるようになるんだ。