shell 脚本逃离疯狂 - 发送单引号到 subshel​​l

shell 脚本逃离疯狂 - 发送单引号到 subshel​​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 命令,但我无法让它执行该命令。它总是抱怨“无效参数”的错误。

基本上,我需要在进入子 shell 的命令中传递大量单引号字符。

发送到 subshel​​l 的最终产品如下所示:

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命令打印了一个有效的 shell 命令,因为您在不包含特殊字符的文件名上尝试过它(特别是,没有单引号 - 就该部分而言$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"

请注意,您没有将任何单引号传递给任何子 shell(您甚至没有运行子 shell)。引号用于解析脚本,不会将引号传递给任何命令。

相关内容