findコマンドの-execで2つのbashコマンドを使用する方法は? GREPによる

findコマンドの-execで2つのbashコマンドを使用する方法は? GREPによる

私も同じことをしたいfindコマンドの-execで2つのbashコマンドを使用する方法は?ただし、2番目のコマンドとしてgrepを使用してください。以前のソリューションに公開されたソリューションは、grepが2番目のコマンドの場合は機能しません。別の問題exec オプションと find コマンドと grep コマンドの組み合わせgrepの使用について質問しましたが、すべての答えはgrepを使用しません。私の考えではgrepをしなければならないと思います。

例えば、

sudo find -D exec . -maxdepth 1 -type f -iname "*" -exec file -N '{}' \; -exec echo 'asdf' \;

うまくいきますが、

sudo find -D exec . -maxdepth 1 -type f -iname "*" -exec file -N '{}' \; -exec grep "JPEG" {} \;

grepが何かをするという証拠はありません。最初のコマンドの標準出力をgrepの標準入力に強制するにはどうすればよいですか?代わりに、ファイルコマンドの出力をファイルにパイプし、そのファイルに対してのみgrepを実行すると正常に動作します。

dell@DELL-E6440:~$ rm junk.txt
dell@DELL-E6440:~$ sudo find -D exec . -maxdepth 1 -type f -iname "*" -exec file -N '{}' >> junk.txt \;
dell@DELL-E6440:~$ grep "JPEG" junk.txt
./150120-ssc-proxy~20190508-061623.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 150x150, segment length 16, baseline, precision 8, 1018x1426, frames 3
./avoid-powered-overfight~20190508-061623.jpg: JPEG image data, JFIF standard 1.01, aspect ratio, density 1x1, segment length 16, comment: "Intel(R) JPEG Library, version [2.0.16.48]", baseline, precision 8, 1048x659, frames 3
dell@DELL-E6440:~$

しかし、要点は、単一のbash行でこれを実行したいと思います>>は、とにかく実行の間にファイルを適切に更新できないことです。

ベストアンサー1

file各ファイルで実行して文字列をgrep出力するには、次のようにします。fileJPEG

find . -maxdepth 1 -type f -exec file {} + | grep JPEG

file通常のファイルバッチで動作し、結果の出力ストリームを生成します。その後、ストリームはgrep特定の文字列を含む行でフィルタリングされますJPEG。改行文字を含むファイル名は、このパイプの出力に誤って表示されます。

問題のコマンドは、コマンド出力ではgrepなくファイル自体で実行されます。すべてのファイル名が対応する述語と一致するため、fileコマンドを使用すると何もfindできません。-iname "*"

または、bash現在のディレクトリのファイルに対して反復を使用します。

shopt -s dotglob nullglob

for name in ./*; do
    mimetype=$( file --brief --mime-type "$name" )
    if [[ $mimetype == */jpeg ]]; then
        printf '"%s" is a JPEG file\n' "$name"
    fi
done

現在のディレクトリの各ファイルに対して報告されているMIMEタイプを使用して、fileJPEGファイルに対応する名前をフィルタリングします。

少し拡張された例:

shopt -s dotglob nullglob

for name in ./*; do
    mimetype=$( file --brief --mime-type "$name" )
    case $mimetype in
        */jpeg)   printf '"%s" is a JPEG file\n'             "$name" ;;
        */png)    printf '"%s" is a PNG file\n'              "$name" ;;
        image/*)  printf '"%s" is some form of image file\n' "$name" ;;
        *)        printf '"%s" is not an image file\n'       "$name"
    esac
done

最後に、以下から直接MIMEタイプを使用してくださいfind

find . -maxdepth 1 -exec bash -c '[[ $(file -b --mime-type "$1") == */jpeg ]]' bash {} \; -print

またはより効果的に、

find . -maxdepth 1 -exec bash -c '
    for pathname do
        [[ $(file -b --mime-type "$pathname") == */jpeg ]] && printf "%s\n" "$pathname"
    done' bash {} +

最後の2つのコマンドは、JPEGイメージに対応するパス名のみを印刷します。

おすすめ記事