[Linux]xargsで繰り返し処理を1コマンドで実行する

2020年10月1日

はじめに

Linuxでファイル操作をすることが多い方に、繰り返し処理で使えるコマンドを紹介します。

xargs

「引数を渡してコマンド実行ができる」コマンドです。
主にパイプ(|)でつないで使います。

使用例

ファイルを用意します。

$ touch {1..3}.tsv
$ ls
1.tsv 2.tsv 3.tsv

基本的な動作

$ ls * | xargs -I {} echo {}
1.tsv
2.tsv
3.tsv

lsの結果をechoしています。
オプション-I 文字列によって、パイプで渡される値をコマンドのどこに代入するか指定できます。

具体的には、lsの結果を1行ずつ{}に代入して、その後のコマンド(echo以降)の{}が登場する箇所で置き換えています。
つまり、以下を実行しているのと同義です。

$ echo 1.tsv
$ echo 2.tsv
$ echo 3.tsv

一括リネーム

prefixをつけるだけなどのシンプルなリネームならこれでいけます。

$ ls [1-3].tsv | xargs -I {} mv {} prefix_{}
$ ls        
prefix_1.tsv prefix_2.tsv prefix_3.tsv

[Linux]大量のファイル名のリネームをコマンド一発で実行するヒントで紹介している方法もありますが、こちらのがサクッと書くことができます。

bqコマンドで一括ロード

xargsのメリットを感じることができたのがbqでのコマンド実行でした。
※BigQueryとbqについての詳しい説明は割愛します。

BigQueryにcliベースで操作ができるコマンドbqは、ファイルを転送してテーブルにロードすることができます。
ただ、ディレクトリの中身を一括で、みたいな処理がやりづらいという課題がありました。

bqのロードコマンド

hoge-data-setのhoge-databaseのhoge-tableにfile_1.csvの中身をロードする、というコマンドです。

$ bq load --source_format=CSV --encoding=UTF-8 hoge-data-set:hoge-database.hoge-table file_1.csv

xargsを使って選択&一括ロード

例えば、test1ディレクトリの、file_XX.csvというファイルのみをロードしたい場合、以下のように書くことで1コマンドで実行できます。

$ ls test1/file_*.csv | xargs -I {} -t bq load --source_format=CSV --encoding=UTF-8 hoge-data-set:hoge-database.hoge-table {}
  • -tオプション : 実行するコマンドを表示します。

終わりに

当たり前かもしれないのですが、Linuxのコマンドを使いこなすだけで、多くのことが効率化できそうです。

このあたりの課題は、Google Spreadsheetを使ったり、スクリプトを少し書けばなまじ解決できてしまうだけに、Linuxの便利コマンドの学習・習得がおろそかになっていました。

今後は意識して使えるコマンドを増やしていこう思います。

参考