입력 데이터의 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

관련 정보