콘텐츠 유형별로(확장자 관계없이) 모든 텍스트 비디오 사운드 및 이미지 파일을 반복하는 방법

콘텐츠 유형별로(확장자 관계없이) 모든 텍스트 비디오 사운드 및 이미지 파일을 반복하는 방법

각 카테고리 텍스트(코드 스크립트 및 src 파일 포함), 비디오, 사운드 및 이미지 파일에 대해 4개의 for 루프를 사용하고 싶습니다.

유사한 검사를 수행하기 위한 명시적 검사 확장

for i in *.ext1 *.ext2 *.ext...

각 카테고리에 대해 가능한 모든 확장을 지정해야 하며 대안을 찾고 있습니다.

답변1

다른 방법이 없을까 두렵습니다. *nix 시스템에서, 따라서 아마도 사용하는 모든 운영 체제에서 확장은 일반적으로 선택 사항이며 외관상이라는 점을 명심하십시오. 이는 확장자가 전혀 없는 파일을 가질 수 있음을 의미합니다.

$ ls
foo1  foo10  foo2  foo3  foo4  foo5  foo6  foo7  foo8  foo9

$ for file in *; do file "$file"; done
foo1: PNG image data, 25 x 25, 8-bit/color RGBA, non-interlaced
foo10: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 22050 Hz
foo2: GIF image data, version 89a, 500 x 225
foo3: HTML document, Unicode text, UTF-8 text, with very long lines (1207)
foo4: MPEG sequence, v2, program multiplex
foo5: Ogg data, Vorbis audio, stereo, 44100 Hz, ~128000 bps
foo6: Audio file with ID3 version 2.2.0, contains: MPEG ADTS, layer III, v1, 160 kbps, 44.1 kHz, JntStereo
foo7: ISO Media, Apple QuickTime movie, Apple QuickTime (.MOV/QT)
foo8: RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps, video: FFMpeg MPEG-4, audio: MPEG-1 Layer 3 (mono, 44100 Hz)
foo9: ASCII text

따라서 유일한 옵션은 파일 형식을 추출한 다음 언급한 범주 중 하나로 분류하는 프로그램을 작성하는 것입니다. 그런 도구가 존재한다면 나는 그것에 대해 모른다.

정말로 파일을 작성하고 싶다면 file위의 방법으로 시작한 다음 어떤 파일 형식이 어떤 카테고리에 속해야 하는지 정의하고 거기에서 가져오면 됩니다. 하지만 이 작업을 수행할 수 있는 쉘 기본 방법은 없습니다.

답변2

@terdon의 답변(간단히 "파일 사용")을 바탕으로 다음을 수행할 수 있습니다.

file --mime-type * |
  awk -F': ' '$2 ~ /^video/ { system("process_video_file.sh " $1) ; next };
              $2 ~ /^image/ { system("process_image_file.sh " $1) ; next };
              $2 ~ /^audio/ { system("process_audio_file.sh " $1) ; next };
              { print "$1: unknown file type $2" }'

물론 , 및 을 스크립트로 작성 process_video_file.sh해야 process_image_file.sh합니다 process_audio_file.sh.

참고: 이 경우 :줄 바꿈이나 시퀀스(콜론 및 공백)가 포함된 파일 이름이 손상될 수 있지만 발생할 가능성은 낮지만 불가능하지는 않습니다.

또는 셸에서 다음과 같은 작업을 수행할 수 있습니다.

while read -r f ft ; do
  case "$ft" in
    video*) process_video_file "$f" ;;
    image*) process_image_file "$f" ;;
    audio*) process_audio_file "$f" ;;
    *) echo "$f: unknown file type $ft" ;;
  esac
done < <(file --mime-type * | sed -e 's/: /\t/')

이는 쉘 스크립트에 있기 때문에 "process_(video|image|audio)_file"을 별도의 쉘 스크립트로 작성하거나 동일한 스크립트에 정의된 쉘 함수로 작성할 수 있습니다. Case 문에 포함할 수도 있습니다(그러나 Case당 문이 여러 개인 경우 코드를 읽을 수 없거나 유지 관리할 수 없게 될 수 있습니다).

참고: 이렇게 하면 공백, 개행, 탭 또는 awk 버전과 동일한 콜론 및 공백 순서로 파일 이름이 구분됩니다.

이러한 파일 이름 문제를 피하기 위해 이 파일(또는 awk 버전)을 다시 작성하는 것은 어렵지 않지만 내 대답의 목적은 완전한 스크립트를 작성하는 것이 아니라 직접 해결할 수 있는 몇 가지 가능한 지침을 보여주는 것입니다.


보다 정교한 대안은 perl과 여러 perl 모듈 중 하나를 사용하여 파일의 MIME 유형을 결정하는 것입니다. 예:파일 유형또는파일::Mime정보.

이 중 어느 것도 셸에 없기 때문에 파일 이름에 대한 셸 인용이나 토큰화 문제가 발생하지 않습니다(즉, 파일 이름에는 문제 없이 유효한 문자가 포함될 수 있습니다). 이것은 fileawk나 쉘을 사용하는 것보다 더 이상 작업이 아니며 더 어렵지도 않습니다.

Perl에 대해 더 자세히 알고 싶다면 Perl에는 멀티미디어 파일의 메타데이터를 처리하기 위한 훌륭한 라이브러리도 있습니다.이미지::Exiftool(이미지 파일에서만 작동하는 것이 아니므로 이름에 속지 마십시오) 또는비디오::정보또는오디오::파일.

Perl에는 외부 오디오 또는 비디오 처리 도구와 C 라이브러리에 대한 인터페이스도 있습니다. 비슷한 기능을 가진 라이브러리도 Python에서 사용할 수 있습니다. 이를 위해서는 처리 중인 파일 유형을 파악하고 실제 처리를 다른 프로그램에 넘겨주는 빠르고 더러운 스크립트보다 더 많은 작업이 필요하지만 비슷한 작업을 수행해야 하는 경우 가능합니다. 노력할 가치가 있거나 노력할 필요가 있습니다. 기존 도구가 수행하지 않거나 필요한 방식으로 작동하지 않는 방식으로 파일을 처리합니다.

관련 정보