LoginSignup
0
0

More than 1 year has passed since last update.

多数のファイルを処理する場合の工夫

Last updated at Posted at 2021-11-21

xargsとGNU Parallelの個別の解説記事や、比較の解説記事は多いようだが、両者を組み合わせて使うと便利であることに気が付き、その解説は少なくとも日本語では見つからないので、以下に解説。

多数のファイルを処理する場合の工夫

  • ここでは「多数のファイルを処理する場合の工夫」と書いたが、ここには分かり安い例示はない。
    • 例示が大きくなりがちなために、例を載せるのがやや困難なため。
    • 従って、下記のコマンド例を実行すれば意味が分かって、cheat sheetのように後で読み返しやすい様に、要点のみを記す。
  • 下記は、あくまで数万個のファイルを対象にする場合である。
    • 数百万個もある場合は、下記の方法だと、各コマンドの起動が10ミリ秒であっても、計算が1日(86400秒)程度かかる。
    • そのような場合は、各コマンドが、数百個のファイルを一度に処理するように工夫すれば良い。そうすると、場合によっては、ここに書いてあるノウハウが再び役に立つであろう。

下記の状況を仮定する

  1. 1個のディレクトリに数万個のデータファイルが存在する。
  2. 何かの処理を手際よく処理したい。
  3. 再現性を高い状態にして、保守性を高めたい。

数万個のファイルが1個のディリクトリにある場合の難点

  • ls は何かを表示するまでの時間がかかる。
    • 比較するとecho * が何倍も高速。
  • less *とするとtoo longなどという警告が出て動かない。
    • これは、echo * | xargs -n 1000 less で対処可能。

その場合の対処法

  • シェルのfor句を使う — 繰り返し処理の指定が簡単に書ける。
    • シェルのfor句の簡単な例: for i in `seq 10` ; do echo $i ; done
  • GNU Parallelを使う — プロセスの並列化が容易に出来て、処理が何倍も速くなる。

    • インストールして、コマンドのparallelを用いる。
    • 例えば次の様な使い方をする。
      • echo * | xargs -n1000 | parallel -C ' ' wc
      • よく使われているかも知れない使い方:
        • :::::::を使った構文の方がもっと基本的かもしれない。
        • {}{1}などを使った書き方も要マスター。
      • しかし、下記で書いたようなことが、私には必要ではあった。
        • 上記の状況への対処に、どうやら xargsのみだと何かが足りない。
        • parallelを使うと一見複雑だが、最も簡潔そうである。
  • Makefileを使う — 保守性と再現性が高まる。

    • 複数の処理にそれぞれ名前を付けて、必要な時に必要な処理が出来る。
      • make proc1 proc2 などを実行すれば良い。
    • ひとつのファイルに、それらの複数の処理内容を書けるので、保守が楽。
      • ただし、シェルのコマンド文中の$i$$iと書き換えたりなどの工夫が厄介かも。

parallelとシェルのfor句を組み合わせる

  1. for文と組み合わせない例(#) :
    • seq 20 | xargs -n8 | parallel -C ' ' echo
  2. for文を組み合わせる例:
    • seq 20 | xargs -n8 | parallel -C ' ' for i in {} \; do echo \$i \; done
    • 上記では、次の様な書き換えが必要となった。
      • $;をエスケープする。parallelに渡す前に直接シェルに解釈させないため。
      • |,",(,),<,>,'などもエスケープが必要。
    • seq 20 | xargs -n8 | parallel -C" " ' for i in {}; do echo $i ; done | tr "\n" " "'とすると、もっと単純。
      • シングルクォート'の間に改行文字を含めてよく、簡単に複数行のコマンド文を埋め込むことが出来る。

Parallelに関して(引用に関する表示)

bash-3.2$ parallel --citation
Academic tradition requires you to cite works you base your article on.
If you use programs that use GNU Parallel to process data for an article in a
scientific publication, please cite:

@software{tange_2021_5593566,
      author       = {Tange, Ole},
      title        = {GNU Parallel 20211022 ('Sinclair')},
      month        = Oct,
      year         = 2021,
      note         = {{GNU Parallel is a general parallelizer to run
                       multiple serial command line programs in parallel
                       without changing them.}},
      publisher    = {Zenodo},
      doi          = {10.5281/zenodo.5593566},
      url          = {https://doi.org/10.5281/zenodo.5593566}
}

(Feel free to use \nocite{tange_2021_5593566})

This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing.

More about funding GNU Parallel and the citation notice:
https://lists.gnu.org/archive/html/parallel/2013-11/msg00006.html
https://www.gnu.org/software/parallel/parallel_design.html#Citation-notice
https://git.savannah.gnu.org/cgit/parallel.git/tree/doc/citation-notice-faq.txt

If you send a copy of your published article to tange@gnu.org, it will be
mentioned in the release notes of next version of GNU Parallel.
0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0