광기를 탈출하기 위한 쉘 스크립트 - 서브쉘 l에 작은따옴표 보내기

광기를 탈출하기 위한 쉘 스크립트 - 서브쉘 l에 작은따옴표 보내기

제 실력이 너무 부족해서 제대로 작동을 못하겠어요...

#!/bin/bash -x
# mxfbc.sh - mxf video file batch converter
# pass at the command line ...
# (1) the directory to batch convert (typically called CLIPS00X from the Canon XF100 and, 
# (2)the file type to convert (typically MXF from the Canon XF100)

# updated 2012-Feb-18

CLIPS_dir="$1"
type="$2"


function ffconvert()
{
#   ffmpeg -i "$1"  -r 30 -f mov -vcodec libx264 -acodec pcm_s16le -map 0:0 -map 0:1 -map 0:2 "${1%%.*}"\.MOV
    ffmpeg -i "$1"  -r 30 -f mov -vcodec libx264 -acodec copy -threads 0 -map 0:0 -map 0:1 -acodec copy -map 0:2 -acodec copy "${1%%.*}"\.MOV
#   ffmpeg -i "$1"  -r 30 -f mov -vcodec copy -acodec pcm_s16le -map 0:0 -map 0:1 -map 0:2 "${1%%.*}"\.MOV
}
#12

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

date
for item in $CLIPS_dir* ; do

if [ -d $item ]; then

    inputs=""
    map=""
    count=0
         #echo -e "Item: $item"
            for file in $item/* ; do

                if [ ${file#*.} = "$type" ]; then
                    #date
                    #echo -e "Now processing: ${file##*/} \n"
                    #echo "File name: ${file%%.*}"
                    #echo "File type: ${file##*.}"
                    #inputs="$inputs -i ${file##*/}"
                    inputs="$inputs -i ""'""$file""'"
                    map="$map[$count:0] [$count:1] [$count:2] "
                    count=$(($count+1)) 

                    # ffconvert "$CLIPS_dir$item/$file"
            #       echo -e "Finished processing: ${file##*/} \n"

                fi
            done
            filter=$map
            #echo -e $inputs
            echo -e $count
            #echo -e $map
            #echo -e $filter


echo ffmpeg "$inputs"" -r 29.97 -f mov -vcodec libx264 -acodec pcm_s16le -threads 0 -filter_complex ""'""$filter""concat=n=""$count"":v=1:a=2 [v] [a1] [a2]'" -map \'[v]\' -map \'[a1]\' -map \'[a2]\' "'""$item"\.MOV"'"
fi

done



# restore $IFS
IFS=$SAVEIFS

스크립트는 현재 완벽한 형식으로 ffmpeg 명령을 에코하지만 명령을 실행할 수는 없습니다. 항상 "잘못된 인수" 오류에 대해 불평합니다.

기본적으로 서브셸에 들어가는 명령에는 작은따옴표 문자를 많이 전달해야 합니다.

서브쉘로 전송된 최종 제품은 다음과 같습니다.

ffmpeg  -i '/Volumes/localtank/card2/CONTENTS/CLIPS001/AA0715/AA071501.MXF' -i '/Volumes/localtank/card2/CONTENTS/CLIPS001/AA0715/AA071502.MXF' -i '/Volumes/localtank/card2/CONTENTS/CLIPS001/AA0715/AA071503.MXF' -i '/Volumes/localtank/card2/CONTENTS/CLIPS001/AA0715/AA071504.MXF' -i '/Volumes/localtank/card2/CONTENTS/CLIPS001/AA0715/AA071505.MXF' -r 29.97 -f mov -vcodec libx264 -acodec pcm_s16le -threads 0 -filter_complex '[0:0] [0:1] [0:2] [1:0] [1:1] [1:2] [2:0] [2:1] [2:2] [3:0] [3:1] [3:2] [4:0] [4:1] [4:2] concat=n=5:v=1:a=2 [v] [a1] [a2]' -map '[v]' -map '[a1]' -map '[a2]' '/Volumes/localtank/card2/CONTENTS/CLIPS001/AA0715.MOV'

편집하다:

알았어...괜찮아...알았어...들어줘서 고마워. 카메라에서 파일(자동 분할된 파일)을 가져와 ffmpeg를 사용하여 다시 연결하거나 연속 비디오로 연결하려는 사용자를 위한 스크립트는 다음과 같습니다. ...

#!/bin/bash -x
# mxfbcc.sh - mxf video file batch converter and concatenate parts into a whole
# pass at the command line ...
# (1) the directory to batch convert (typically called CLIPS00X from the Canon XF100 and, nothing else

# updated 2013-April-3

CLIPS_dir="$1"


function ffconvert()
{
#   ffmpeg -i "$1"  -r 30 -f mov -vcodec libx264 -acodec pcm_s16le -map 0:0 -map 0:1 -map 0:2 "${1%%.*}"\.MOV

    ffmpeg -i "$1"  -r 30 -f mov -vcodec libx264 -acodec copy -threads 0 -map 0:0 -map 0:1 -acodec copy -map 0:2 -acodec copy "${1%%.*}"\.MOV
#   ffmpeg -i "$1"  -r 30 -f mov -vcodec copy -acodec pcm_s16le -map 0:0 -map 0:1 -map 0:2 "${1%%.*}"\.MOV

}
#12

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")

date
for item in $CLIPS_dir* ; do

if [ -d $item ]; then

    inputs=""
    map=""
    count=0
         #echo -e "Item: $item"
            for file in $item/* ; do

                if [ ${file#*.} = "MXF" ]; then
                    #date
                    #echo -e "Now processing: ${file##*/} \n"
                    #echo "File name: ${file%%.*}"
                    #echo "File type: ${file##*.}"
                    #inputs="$inputs -i ${file##*/}"
                    input+="-i '${file}' "
                    map="$map[$count:0] [$count:1] [$count:2] "
                    count=$(($count+1)) 

                    # ffconvert "$CLIPS_dir$item/$file"
            #       echo -e "Finished processing: ${file##*/} \n"

                fi
            done
            filter=$map
            #echo -e $inputs
            #echo -e $count
            #echo -e $map
            #echo -e $filter
            #echo -e 


eval ffmpeg ${input} -r 29.97 -f mov -vcodec libx264 -acodec pcm_s16le -threads 0 -filter_complex \'$filter concat=n=$count:v=1:a=2 [v] [a1] [a2]\' -map \'[v]\' -map \'[a1]\' -map \'[a2]\' \'$item\.MOV\'
fi

done



# restore $IFS
IFS=$SAVEIFS

답변1

이 방법으로 파일 이름 목록을 저장할 수 없습니다 inputs. inputs문자열이므로 '파일 이름의 공백과 문자열에 추가된 공백을 구별할 수 없습니다. 그건 그렇고, inputs="$inputs -i ""'""$file""'"이것은 혼란스러운 작성 방법입니다 inputs="$inputs -i '$file'"(예: 공백, -i공백, 작은따옴표, 파일 이름 및 다른 작은따옴표 추가).

귀하의 echo명령은 특수 문자가 포함되지 않은 파일 이름에 대해 시도했기 때문에 유효한 쉘 명령을 인쇄합니다(특히 작은따옴표가 없습니다. $inputs해당 부분에 관한 한 다른 모든 문자는 괜찮습니다). 아니 echo, 그냥 달리고 있는 거야

ffmpeg "$inputs -r 29.97 -f mov -vcodec libx264 -acodec pcm_s16le -threads 0 -filter_complex '${filter}concat=n=$count:v=1:a=2 [v] [a1] [a2]'" \
       -map \'[v]\' -map \'[a1]\' -map \'[a2]\' \'$item\.MOV\'

(중복된 인용문을 단순화했습니다.) 전체 문자열까지 [a1] [a2]매개변수라는 점에 유의하세요.

명령에 대한 여러 인수를 저장하려면 배열을 사용하십시오. 명령을 실행할 때 모든 변수 대체( "$foo"또는 배열의 경우 "${foo[@]}") 주위에 큰따옴표를 사용하십시오. 따옴표 주위에 따옴표를 넣지 마십시오. 그렇지 않으면 리터럴 따옴표 문자가 ffmpeg명령에 전달됩니다.

inputs=()
    inputs+=(-i "$file")
ffmpeg "${inputs[@]}" -r 29.97 -f mov \
       -vcodec libx264 -acodec pcm_s16le -threads 0 \
       -filter_complex "${filter} concat=n=$count:v=1:a=2 [v] [a1] [a2]" \
       -map '[v]' -map '[a1]' -map '[a2]' "$item.MOV"

서브셸에 작은따옴표를 전달하지 않는다는 점에 유의하세요(서브셸을 실행하지도 않습니다). 따옴표는 스크립트를 구문 분석하는 데 사용되며 어떤 명령에도 전달되지 않습니다.

관련 정보