이 줄이 파일을 손상시키는 이유는 무엇입니까?

이 줄이 파일을 손상시키는 이유는 무엇입니까?

일부 비디오를 일괄 인코딩하는 데 도움이 되도록 다음을 작성했습니다.

find -name '*.mkv' -exec HandBrakeCLI -Z "Android Tablet" \
  -c "1-3" -m -O --x264-tune film -E copy --decomb -s 1 -i {} \
  -o `echo {} | tr mkv m4v` \;

그러나 이는 치명적으로 실패합니다. 모든 700-900MB 파일을 36KB 파일로 대체합니다.

HandBrake는 인코딩을 진행할 때만 비디오 파일의 속성을 읽고 인쇄할 수 있다는 점은 주목할 가치가 있습니다. 파일이 유효하지 않기 때문입니다. 그래서 도착하면 덮어쓰기가 일어나는거 같은데...

-o `echo {} | tr mkv m4v`

...하지만 왜 이런 일이 발생하는지 모르겠습니다. 출력 파일 이름을 everything.mkv에서 everything.m4v로 변경하고 싶습니다.

파일 이름에 공백이 없습니다. 12-the-revenge.mkv예를 들어, 다음과 같은 형식입니다.

답변1

역따옴표 표현: ( echo {} | tr mkv m4v즉,아니요다양한 이유로 아래 참조)가 find 명령을 구문 분석할 때 한 번 확장됩니다. 를 사용하면 bash일반적으로 다음과 같이 확장됩니다 {}.

$ echo {} | tr mkv m4v
{}

실제로 이것은 빈 줄을 출력하는 fish를 제외하고 내 컴퓨터에 설치된 모든 쉘에서 발생합니다. 하나를 사용하지 않는다고 가정하면 fish실제로 표시되는 매개변수 find는 다음과 같습니다.

find -name '*.mkv' -exec HandBrakeCLI -Z "Android Tablet" \
-c "1-3" -m -O --x264-tune film -E copy --decomb -s 1 -i {} \
-o {} \;

간단히 말해서 HandBrakeCLI입력과 출력 모두 동일한 파일이 제공되며 증상에 대한 설명이 정확하지는 않지만 이것이 여러분이 보고 있는 것이라고 생각합니다.

불행하게도 find가 작업에서 수행하려는 확장된 대체를 수행하도록 하는 쉬운 방법은 없습니다 -exec. 에 명령을 전달하면 이 작업을 수행할 수 있지만 bash -c이 경우 명령줄에 추가로 인용이 포함되어 혼란스럽습니다. 더 깔끔하고 읽기 쉬운 솔루션은 해당 인수를 반복하는 셸 스크립트 파일을 만드는 것입니다.

파일: ( mkvtom4v.sh꼭 확인해주세요 chmod a+x mkvtom4v.sh)

#!/bin/bash
for file in "$@"; do
  HandBrakeCLI -Z "Android Tablet" -c "1-3" -m -O \
               --x264-tune film -E copy --decomb -s 1 \
               -i "$file" -o "${file/%.mkv/.m4v}"
done

그런 다음 find로 호출하십시오.

find /path/to/directory -name '*.mkv' -exec /path/to/mkvtom4v.sh {} +

몇 가지 참고사항:

  1. 백틱( )을 사용하지 마십시오 some command. 수년 동안 더 이상 사용되지 않습니다. 를 사용하면 $(some command)더 읽기 쉽고 중첩이 가능합니다.

  2. tr확실히 당신이 원하는 것이 아닙니다. 문자별로 번역합니다. 예를 들어, tr aeiou AEIOU이렇게 하면 모든 모음이 UppErcAsE가 됩니다. 모두 tr mkv m4v로 변경됩니다 . 자세한 내용은 (또는 )을 참조하세요 .k4man trinfo tr

  3. "${file/%.mkv/.m4v}"bash의 특수 검색 및 대체 구문입니다. 이 경우 이는 다음을 의미합니다. "값을 가져와서 ( 이 문맥에서는 "다음으로 끝남"을 의미함) $file끝나는 경우 " 로 바꿉니다 . 변수 값을 편집하는 방법은 여러 가지가 있습니다. "매개변수 확장"을 검색해 보세요..mkv%.m4vman bash

  4. GNU find를 사용하면 명령 끝에 (대신 )을 {} +사용할 수 있습니다 . 가능한 한 많은 검색된 파일 이름으로 대체됩니다. 자세한 내용은 참조하십시오 .-exec\;info find

관련 정보