入力データのawkと改行

入力データのawkと改行

ディレクトリ内のファイルを見つけ、そのファイルのMIMEタイプで識別したいと思います。いいえファイル拡張子として。

このコマンドを使用してMIMEタイプを決定します。

% find . -type f -print0 | xargs -0 -I{} file --mime-type {}
./foo
bar.png: image/png
./OWoHp.png: image/png
./J7ZwV.png: image/png
./foo.txt: inode/x-empty
./bar: inode/x-empty
./hUXnc.png: image/png

最初のファイルのファイル名には改行文字があります。

% ls foo$'\n'bar.png
foo?bar.png

大丈夫です。ファイルは大丈夫でしょう。いいえ名前が変更されました。

次のコマンドを使用して、画像ではなくすべてのファイルをフィルタリングしたいと思います。

% find . -type f -print0 | xargs -0 -I{} file --mime-type {} | awk -F$"\0" -F": " '/image/ {print $1}'
bar.png
./OWoHp.png
./J7ZwV.png
./hUXnc.png

サイズを決定します。

% find . -type f -print0 | xargs -0 -I{} file --mime-type {} | awk -F$"\0" -F":" '/image/ {print $1}' | xargs -I{} identify -format "%[fx:w*h] %i\n" {}
identify: unable to open image `bar.png': No such file or directory @ error/blob.c/OpenBlob/2709.
identify: unable to open file `bar.png' @ error/png.c/ReadPNGImage/3922.
26696 ./OWoHp.png
47275 ./J7ZwV.png
37975 ./hUXnc.png

しかし、.という名前のファイルがないため動作しませんbar.png。正確な名前は

./foo
bar.png

名前に改行文字があります。

答え1

私の考えに最適なオプションは、xargsの代わりにシェルループを使用することです。これにより、コマンドがファイル名引数を送信する方法を制御できます。

find . -type f -print0 | 
while IFS= read -rd "" filename; do
    type=$( file --brief "$filename" )
    if [[ $type == *image* ]]; then
        identify -format "%[fx:w*h] %i\n" "$filename"
    fi
done

答え2

-exec sh -c '...'次の設定を使用できますfind

find . -type f -exec sh -c 'file --brief --mime-type "$0" | \
grep -q ^image/ && identify -format "%[fx:w*h] %i\n" "$0"' {} \;

または次のようにexiftool

exiftool -q -if '$mimetype =~ /image/' -p '$megapixels $directory/$filename' -r .

答え3

Steeldriverが指摘したように、問題はそうではありませんawk。提供した入力を食べたため、fileNULはありません。私はすべてをシェルでやります:awkfile

find . -type f -print0 | while IFS= read -r -d '' file; do 
    file --mime-type "$file" | grep -qP "\bimage/" && 
        printf '%s %s\0' $(identify -format '%[fx:w*h]' "$file") "$file";
done | sort -gz | tr '\0' '\n'
256 ./file 10
256 ./file 15
484 ./file 16
576 ./file 11
576 ./file 17
1024 ./file 12
1024 ./file 19
2304 ./file 13
5625 ./file 14
15190 ./file 2
15680 ./file 1
16384 ./file 9
65536 ./file 18
145200 ./file 0
183531 ./file 6
364807 ./file
3
364807 ./file 4
364807 ./file 5
388245 ./file 8
550560 ./file 7

sort回答を改善しようとしていると仮定して参加しています。ここ。上記の例は、スペースとfile\n3改行を含むファイル名に対して実行されました。何らかの理由で - 終了行がidentify印刷されず、代わりに使用しました。\0printf

関連情報