find:ディレクトリを処理し、結果を見つけたディレクトリに書き込みます。

find:ディレクトリを処理し、結果を見つけたディレクトリに書き込みます。

ディレクトリを見つけてここにコマンドを適用したら、結果が見つかったディレクトリにパイプする必要があります。

find -type d与えられたと仮定

.
./cortexa53-crypto-mx8mp
./cortexa53-crypto
./imx8mp_sp
./all

私は次のことを考えました。

find -type d -exec '~/bin/opkg-utils/opkg-make-index {} | gzip > {}/package.gz'  \;

結果は次のとおりです。

find: '~/bin/opkg-utils/opkg-make-index ./cortexa53-crypto-mx8mp | gzip > ./cortexa53-crypto-mx8mp/package.gz': No such file or directory

しかし、そのコマンドを実行すると(内部に何があるのか' '​​)動作します! ? ! ?

ボーナス質問:それを見つけるのを避ける方法は.

答え1

のパラメータを使用して単純なコマンドよりも複雑なコマンドを実行する必要がある場合は、-execインラインスクリプトで次の手順を実行します。

find . -type d -exec sh -c '
    tmpfile=$(mktemp) || exit
    trap "rm -f \"\$tmpfile\"" EXIT

    for dirpath do
        "$HOME"/bin/opkg-utils/opkg-make-index "$dirpath" | gzip -c >"$tmpfile" &&
        cp -- "$tmpfile" "$dirpath"/package.gz
    done' sh {} +

これにより、一括ディレクトリパスがインラインsh -cスクリプトにパラメータとして渡されます。この短いスクリプトはこれらのパスを繰り返し、各パスに対してユーティリティを呼び出し、圧縮された出力を一時ファイルに書き込みます。ファイルが書き込まれると、ディレクトリに移動され、ループは次のディレクトリに進みます。

これはサブディレクトリで繰り返されます。

.検索の使用を避けるには、次の手順を実行します! -path .

find . ! -path . -type d -exec sh -c '...' sh {} +

または、GNU find(およびその他の一部)の場合は、以下を使用してください-mindepth 1

find . -mindepth 1 -type d -exec sh -c '...' sh {} +

サブディレクトリが繰り返されるのを防ぐには、ディレクトリ-pruneを見つけたらすぐに次のようにします。

find . ! -path . -type d -prune -exec sh -c '...' sh {} +

またはGNUの場合は、次をfind使用します-maxdepth 1

find . -mindepth 1 -maxdepth 1 -type d -exec sh -c '...' sh {} +

ただし、再帰を使用せずに単一のディレクトリにのみ興味がある場合は、シェルループを使用できます。

shopt -s nullglob dotglob

tmpfile=$(mktemp) || exit
trap 'rm -f "$tmpfile"' EXIT

for dirpath in */; do
    dirpath=${dirpath%/}
    [ -h "$dirpath" ] && continue

    "$HOME"/bin/opkg-utils/opkg-make-index "$dirpath" | gzip -c >"$tmpfile" &&
    cp -- "$tmpfile" "$dirpath"/package.gz
done

これは実行されたインラインスクリプトのループと基本的に同じですfindが、スクリプトなので、意図した操作bashのいくつかを実行する必要があります(ワイルドカード隠し名前の有効化、シンボリックリンクではないことを確認するなど)。 。 )find$dirpath

関連情報