Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2722

パイプライン処理楽しい!

$
0
0
はじめに ふざけたタイトルをつけてしまったので、内容をざっくりと説明すると、「あるディレクトリに含まれているファイルのうち(ファイル名でソートされているものとして)上からn個のファイルを別ディレクトリにまとめてコピーする」ということを(シェルスクリプトを書いたりしてゴニョゴニョするのも面倒なので)1行のコマンドで行えないものかと思い、調査した際の備忘録になります。 上記の目的を果たすためにどうしたかを述べただけであり、体系的にまとまっているわけではない点はご容赦ください。 設定 状況設定として/Datasets/Aというディレクトリにdata00.h5 ~ data99.h5という100個のデータがあり、このうち上から20個を/Datasets/Bというディレクトリにコピーしたいとします(ここではh5データを仮定していますが、h5データでなくても問題ありません)。 上から10個であれば、ワイルドカードを使って $ cp /Datasets/A/data0*.h5 /Datasets/B/. などとすることもできますが、このやり方では10個以外の場合ではうまくいきません。 そこで、lsコマンドやheadコマンドなどをうまく組み合わせて、ディレクトリにある任意の数のデータをまとめてコピーしたいというのが今回の趣旨になります。 パイプライン処理について まず簡単にパイプライン処理についておさらいしたいと思います。 パイプライン処理というのは、あるコマンドの出力を別のコマンドの入力として使うことで、複数のコマンドを繋げパイプラインにして行う処理のことです。 例として、先程の/Datasets/Aにあるデータのうち上から5個だけを表示するには次のようにします。 ~/Datasets/A$ ls -1 | head -5 ls -1はディレクトリ内のファイルの一覧をリストとして縦に出力するコマンドです。 これを実行すると次のようになります。 ~/Datasets/A$ ls -1 data00.h5 data01.h5 (中略) data99.h5 またhead -5は入力のうち上から5行だけを表示するコマンドになっていて、|で二つのコマンドを繋ぐことで、ls -1の出力をhead -5の入力とすることができ、その出力は次のようになります。 ~/Datasets/A$ ls -1 | head -5 data00.h5 data01.h5 data02.h5 data03.h5 data04.h5 本題 ディレクトリ内のファイルのうち上位20件をコピーするには、パイプライン処理を使ってlsコマンド、headコマンド、そしてcpコマンドを組み合わせると上手くいきそうな気がします。 しかし、cpでは二つ引数を取ることが問題になります。つまり ~/Datasets/A$ ls -1 | head -20 | cp /Datasets/B/. のようにしてしまうと、/Datasets/B/というのがコピー元のパスなのかコピー先のパスなのかが明らかでなく、エラーが出てしまいます。 そこでxargsというコマンドを用います。 xargsコマンドというのは「パイプライン処理を明示的に行うためのコマンド」というように筆者は理解しています。用途としては様々あるのですが、ここでは-iというオプションにより、直前のコマンドの出力を次のコマンドのどの位置で引数にするかを指定できることを利用します。 つまり、これによりls -1 | head -20の出力をcpコマンドの一つ目の引数とすることを明示的に指示することが可能になります。具体的には次のようにします。 ~/Datasets/A$ ls -1 | head -20 | xargs -i cp {} /Datasets/B/. -iオプションを使うことで{}の位置に直前のコマンドの出力が入力されます。 以上のようにすることで、ディレクトリ/Datasets/Aにあるファイルのうち上から20個のファイルdata00.h5 ~ data19.h5を無事、ディレクトリDatasets/Bにコピーすることができました。 おわりに やったこととしては全然大したことはやっていないのですが、パイプライン処理は上手く組み合わせると何でもできる気がしてきて楽しいですね。今回は「xargsコマンドってすごいね!パイプライン処理楽しい!」っていうお話でした。

Viewing all articles
Browse latest Browse all 2722

Trending Articles