xargs에서 두 개의 매개 변수를 한 번에 사용하려면 어떻게해야합니까? 이름을 어떻게

비디오를 변환해야하지만 어디에 있는지 모릅니다. 따라서 비디오가 필요 find합니다. FFmpeg를 사용 하여 결과와 출력 파일 이름을 어떻게 지정할 수 xargs있습니까?

이 명령으로 두 개의 매개 변수를 구성 할 수 있다는 것을 이미 알았습니다.

find . -iname "*.mov" -printf "%p %f\n"

xargs매뉴얼 과 관련된 것을 찾을 수 없습니다 . 나는 이런 것을 원한다.

find . -iname "*.mov" -printf "%p %f\n" | xargs ffmpeg -i {param1} -f flv {param2}

어떻게해야합니까?



답변

이와 같은 것은 트릭을 수행하고 전체 경로를 유지하고 공간을 처리하며로 이름 folder/movie.mov을 바꾸는 folder/movie.flv등의 작업을 수행합니다.

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "${movie%.mov}.flv"
done

그리고 내가 당신을 오해하고 현재 디렉토리에있는 모든 .flv 영화를 원한다면, 이것을 대신 사용하십시오 :

find . -name "*.mov" | while read movie;do
  ffmpeg -i "$movie" -f flv "$(basename "${movie%.mov}.flv")"
done


답변

사람들 xargs이 find와 함께 사용하는 이유 는 여러 파일 이름이 프로그램이 xargs시작될 때마다 동일한 프로그램 호출로 전달되기 때문 입니다. 예를 들어 foo , barbazfind 파일을 반환 하면 다음이 한 번만 실행 됩니다.mv

find sourceDir [...] -print0 | xargs -0 mv -t destDir

효과적으로 mv다음과 같이 호출됩니다 .

mv -t destDir foo bar baz

당신이 할 필요는 없다을하거나 (여기의 경우 가정으로)이 동작을 원한다면, 당신은 간단하게 사용할 수있는 find‘들 -exec.


이 경우 쉬운 해결책은 다음과 같이 짧은 쉘 스크립트를 작성하는 것입니다.

#!/usr/bin/env bash
[[ -f "$1" ]] || { echo "$1 not found" ; exit 1 ; }
P="$1"
F="$( basename $P )"
ffmpeg -i "$P" -f flv "$F"

다른 이름으로 저장 myffmpeg.sh하고 실행하십시오 chmod +x myffmpeg.sh. 그런 다음 다음을 실행하십시오.

find . -iname "*.mov" -exec /path/to/myffmpeg.sh {} \;

발견 된 모든 파일에 대해 쉘 스크립트를 한 번 호출합니다. 쉘 스크립트는 전체 경로에서 파일 이름을 추출 ffmpeg하고 적절한 인수를 사용하여 호출 합니다.


답변

나는 예상했던 해결책을 얻지 못했기 때문에 내 자신을 알았습니다. @Daniel의 대답은 좋지만 쉘 스크립트가 필요합니다. 하나의 라이너가 더 빠르며 스크립트를 작성하는 것보다 더 나은 솔루션이 더 좋습니다.)

하나의 인수 basename를 사용하여 처리하고 사용할 수 있습니다.sh -c

find . -iname "*.mov" -print0 | xargs -0 -i sh -c 'ffmpeg -i {} -f flv `basename {}`'

-i는 xargs에게 {}현재 인수 로 대체하도록 지시합니다 .
”안의 명령 출력은 표준 출력 (bash 기능) basename {}으로 인쇄되므로 기본 파일 이름으로 평가되어 인쇄됩니다.
특수 파일 이름을 올바르게 처리하려면 -0이지만 find와 함께 -print0 옵션을 사용하여 매개 변수를 전달해야합니다.


답변

당신은 거기에있는 모든 대답처럼해야하지만 xargs의 정확한 사용은 다음과 같습니다.

echo argument1 argument2 argument3 | xargs -l bash -c 'echo this is first:$0 second:$1 third:$2' | xargs

따라서 귀하의 경우에는 다음과 같습니다.

find . -iname "*.mov" -printf "%p %f\n" | xargs -l bash -c 'echo ffmpeg -i $0 -f flv $1' | xargs

추신 : 이것은 xargs하나의 xargs명령으로 여러 매개 변수에 대한 정답을 정확하게 찾는 사람들을 위해 xargs에 대한 질문에 대답합니다 .


답변

find 명령 의 결과 형식에 맞게 ffmpeg 의 옵션을 단순히 이동하지 않는 이유는 무엇 입니까?

find . -iname "*.mov" -printf "%p %f\n" | xargs -r -n2 ffmpeg -f flv -i

.mov 파일이 없으면 ffmpeg 가 실행되지 않도록 xargs-r 옵션을 추가하십시오 .

xargs-n2 옵션을 추가하여 xargs 프로세스 수를 한 번에 2 개로 제한했습니다 . 이 경우 항목은 파일 경로와 파일 이름입니다. -n 옵션을 설정 하지 않으면 xargs 는 단일 실행에서 가능한 많은 입력 항목을 처리합니다.


답변

xargs로 할 수 있는지 또는 어떻게 할 수 있는지 잘 모르겠습니다.

그러나 이와 같은 것이 당신을 위해 작동해야합니다 :

find . -iname "*.mov" -printf "%p %f\n" | while read -a HR ; do echo ffmpeg -i ${HR[0]} -f flv ${HR[1]} ;done


답변

이름 바인딩을 사용하고 파일 이름에 공백이 생기지 않도록 다른 구분 기호를 사용하는 Zoredache의 답변에 대한 대안 :

IFS="\t" find -iname "*.mov" -printf "%p\t%f\n" | while read path file; do
    ffmpeg -i $path -f flv $file
done

물론 find -a array다른 대답이 사용한 인수 와 함께 구분 기호를 사용할 수도 있지만 때로는 명명 된 인수가 더 이해하기 쉽습니다.