狂気を逃れるためのシェルスクリプト - サブシェル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

このようにファイル名のリストを保存することはできませんinputsinputs文字列なので、'ファイル名のスペースと文字列に追加されたスペースを区別することはできません。ちなみに、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"

サブシェルに一重引用符を渡さないことに注意してください(サブシェルを実行しません)。引用符はスクリプトを解析するために使用され、どのコマンドにも渡されません。

関連情報