-->

2009-11-22

ファイルの一覧をパイプ付きのコマンドに渡す

$ find * -type d | while read -r d;do echo $d include `ls "$d" | wc -l` files; done
http://ameblo.jp/pclindesk/entry-10131168430.html

この記事が参照サイトの情報のみなので、追記します。

(例1) dev-php5 のパッケージのファイルを /tmp/ にコピーするコマンドを出力する。
find /usr/portage/dev-php5/*/Manifest -exec grep ^DIST {} \; | awk '{print $2}' |sort|uniq|while read -r f;do test -e /usr/portage/distfiles/$f; if [ $? -eq 0 ];then echo cp -f /usr/portage/distfiles/$f /tmp/;fi; done

Manifest というファイルの DIST で始まる行にファイルに関する情報が有り、その行を複数ファイルにまたがって取得します。
find /usr/portage/dev-php5/*/Manifest -exec grep ^DIST {} \;

行ごとにスペースで分けて2カラム目を取得します。取得している値はファイル名です。
| awk '{print $2}'

この部分で重複するファイル名を1つにします。
|sort|uniq

ファイルをコピーするコマンドを出力します。
|while read -r f;do test -e /usr/portage/distfiles/$f; if [ $? -eq 0 ];then echo cp -f /usr/portage/distfiles/$f /tmp/;fi; done

インデントしてコメントを追加しました。
|                                       # パイプです。
while read -r f; do                     # ここから done までで1行ごとにパイプから来た値を読みます。
    test -e /usr/portage/distfiles/$f;  # file が存在すれば真 を返します。
    if [ $? -eq 0 ]; then               # $? が test の戻り値で 0 だと正常です。
        echo cp -f \                    # ここは command > output.txt などとしてコマンドの
            /usr/portage/distfiles/$f \ #   確認をするために echo としています。
            /tmp/;                      # バックスラッシュ(半角の¥)はコマンドの長い時の折り返しの
    fi;                                 #   意味に、この場合はなります。
done                                    # 読み込む行があれば while の最初から処理を続行します。

この例だと説明になっていませんが
while ... done の間にパイプ(|)を含むコマンドの記述が可能です。
また、あらかじめ emerge --fetchonly などでダウンロードしていないとcpコマンドがエラーになります。

また find の -exec は2つ以上かけるので場合によっては、それで十分です。
$ find /tmp/ -exec test -f {} \; -exec md5sum {} \; # これは意味の無い使い方です。 
$ find /tmp/ -type f -exec md5sum {} \;             # これは上記のコマンドと同じです。

0 件のコメント: