概要
パイプラインを用いたコマンドとxargsの使い方がよくわからなかったので自分なりにまとめた。
パイプライン
- パイプ
command1 | command2
はcommand1の出力をcommand2の入力として渡す操作。
簡単な例
echo "hello world!" | tee a.txt
これを実行すると、a.txtというファイルにhello world!
と書き込まれる。
-
echo
は引数をそのまま出力する -
tee
は入力を引数で指定したファイルに書き込む
echo
で出力する値"hello, world"がファイル出力のコマンドtee
の入力として渡された。
なお上記の操作は以下のコマンドでもほぼ同じ。
echo "hello world!" >> a.txt
xargs
-
command1 | xargs command2
でcommand1の出力をcommand2の引数として渡すことができる。
簡単な例
echo b.txt | xargs touch
これを実行すると、b.txt
というファイル名のファイルが生成される。
-
echo
は引数をそのまま出力する -
touch
は引数で指定された名前のファイルを生成する
便利な使用例
パイプライン|
とxargs
を使うことで色々便利なことができる。
便利操作1. ディレクトリ内のファイルに対してファイル内検索を行う
準備
現在のディレクトリには(先述した操作で)以下のファイルができている。
ls
>> a.txt b.txt
また、a.txt
内には"hello, world!"という文字列が入っている。
grep hello a.txt
>> hello, world!
ついでにb.txt
には何も文字列は含まれていない。
grep hello b.txt
>>
ls
の結果に対してgrep
この操作をまとめて、「現在のディレクトリに存在するファイルの中を検索」する操作をしてみる。
ls | xargs grep "hello"
以下の出力となる。
a.txt:hello, world!
- lsで受け取ったファイル名を1個ずつ
grep
の引数に渡す -
grep
にa.txt
を受け取った際に一致する文字列を出力する
また、findを用いれば条件に当てはまるファイルのみに対してgrep
を適用することができる。
find . -name "*.txt" | xargs grep "hello"
-
find [Path] -name [name]
で指定したディレクトリ内でファイルを名前検索できる。今回はa.txt
b.txt
の二種が該当する。
オマケ
xargsを抜いたらどうなるでしょうか?
ls | grep a
出力は以下のようになる。
a.txt
-
grep [Pattern] [File]
という構文においてFileの部分を省略すると、Fileは入力から受け取る。 - そこに対して
ls
の出力であるa.txt b.txt
を渡したためその文字列から検索されて指定したパターンa
に一致するa.txt
がgrepによって抽出された。
便利操作2. 連番を振ったファイルを作る
seq 1 5 | xargs -i touch {}.txt
これを実行すると、1.txt
2.txt
3.txt
4.txt
5.txt
と番号が振られたファイルが生成される。
-
seq i j
でiからjまでの数を順番に出力する。iを省略したら1からスタートするのでこの場合はseq 5
でも同じ。 -
xargs -i
とすると、得られた出力値が{}
内で受け取ることができる。
ほか
12種類のxargs使用例が掲載されている記事
https://www.tecmint.com/xargs-command-examples/