LoginSignup
0
0

More than 1 year has passed since last update.

[訂正あり] 【Bash】xargsの代わりにwhile readで個別ファイルにリダイレクト

Last updated at Posted at 2023-04-17

TL;DR

bash
$ ls *.zip | { while read zip_name; do md5sum $zip_name > $zip_name.md5; done; }

やりたいこと

hoge.zipのmd5sumをhoge.zip.md5として保存したい。
fuga.zippiyo.zipも同様に処理したい。

bash
$ ls
hoge.zip fuga.zip piyo.zip

試したけど駄目だった方法

$ ls *.zip | xargs -I{} md5sum {} > {}.md5

これをすると{}.md5が保存されてしまう。
xargsはリダイレクト先の文字列を置き換えられないようだ。

変数を経由する

標準入力をリダイレクト先にまで反映させたい、というだけなので、素朴に変数を使う。
bashでパイプ(標準入力)から受け付けた内容を変数に代入する
この記事でreadcatを使う方法が載っていた。

bash
$ #readを使う場合
$ #標準入力が変数zip_nameに書き込まれる。ただし標準入力が複数あった場合、最初の1つのみ
$ ls *.zip | { read zip_name; md5sum $zip_name > $zip_name.md5; }
bash
$ #catを使う場合
$ #標準入力が変数zip_nameに書き込まれる。標準入力が複数あった場合、配列として読み込まれるため失敗する。
$ ls *.zip | { zip_name=$(cat); md5sum $zip_name > $zip_name.md5; }

複数ファイルに対応する

いずれの場合も複数ファイルには対応できないので改良が必要になる。
while read zip_name; do ~ done;かな……長すぎて嫌だな」としばらく悩んでいたが、何のことはなくxargsを一度挟めば良いだけだった。

bash
$ #xargsで1つずつreadに送る
$ ls *.zip | xargs echo | { read zip_name; md5sum $zip_name > $zip_name.md5; }

さらにxargs引数を省略するとデフォルトでechoを実行するので、

bash
$ #xargsで1つずつreadに送る(改)
$ ls *.zip | xargs | { read zip_name; md5sum $zip_name > $zip_name.md5; }

これで完成。

23/04/19 指摘を受け記述を削除

コメント欄で動作しないとの指摘を受け確認したところ、確かに動作しなかった。
@ko1nksm さん、ありがとうございます!

bash
$ ls
dummy2.zip  dummy.zip
$ ls *.zip | xargs | { read zip_name; md5sum $zip_name > $zip_name.md5; }
-bash: $zip_name.md5: ambiguous redirect

誤った情報を記載してしまったことを深くお詫び申し上げます。

取り急ぎ上記内容を打ち消し線で示しつつ、最終的な解決方法は週末にデバッグすることとする。

先行記事

xargs リダイレクトで検索すると複数の記事がヒットする。
xargs は個別ファイルへ書き出すリダイレクトのパイプが使えない → for を使う
forを使う方法。
xargsで個別ファイルにリダイレクト
関数化する方法。
xargsで個別のファイルにリダイレクトしたい
shのサブシェルを呼ぶ方法。

本記事のタイトルも先行記事に倣った。
どれを使っても基本的には問題なさそう。

参考

bashでパイプ(標準入力)から受け付けた内容を変数に代入する
xargs は個別ファイルへ書き出すリダイレクトのパイプが使えない → for を使う
xargsで個別ファイルにリダイレクト
xargsで個別のファイルにリダイレクトしたい
xargsを使う際にはechoは書かなくてもよいことをmanページから知った

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