簡體   English   中英

將bash中帶有空格的文件名腳本變量傳遞給外部程序(ffmpeg)失敗

[英]passing script variable of filename with spaces in bash to external program (ffmpeg) fails

小故事:我正在嘗試編寫一個腳本,該腳本將使用 FFmpeg 將存儲在一個目錄中的許多文件轉換為“標准”mp4 格式,並將轉換后的文件保存在另一個目錄中。 這是一次學習經歷(一次有趣的經歷!),因為自從在 IBM 370 大型機上使用 Pascal 和 FORTRAN 很流行以來,我還沒有進行任何真正的編碼。

本質上,腳本獲取文件名,去除路徑和擴展名,用路徑和 mp4 擴展名重新組合文件名,並使用一些設置參數調用 FFmpeg 進行轉換。 如果該目錄僅包含名稱中沒有空格的視頻文件,則一切正常。 如果文件名包含空格,則 FFmpeg 無法處理該文件並繼續處理下一個文件。 該錯誤表明 FFMpeg 只能看到文件名直到第一個空格。 我在下面包含了腳本和輸出。

感謝您提供的任何幫助和建議。 如果您認為我應該以另一種方式這樣做,請務必給我您的建議。 正如我所說,我已經很久沒有做這樣的事情了。 不過我很享受。

我首先包含代碼,然后是示例輸出。

for file in ./TBC/*.mp4
    do

    echo "Start of iteration"
    echo "Full text of file name:" $file

    #Remove everything up to  "C/" (filename without path)
    fn_orig=${file#*C/}
    echo "Original file name:" $fn_orig

    #Length of file name
    fn_len=${#fn_orig}
    echo "Filename Length:" $fn_len

    #file name without path or extension
    fn_base=${fn_orig:0:$fn_len-4}
    echo "Base file name:" $fn_base

    #new filename suffix
    newsuffix=".conv.mp4"

    fn_out=./CONV/$fn_base$newsuffix
    echo "Converted file name:" $fn_out

    ffmpeg -i $file -metadata title="$fn_orig" -c:v libx264 -c:a libfdk_aac -b:a 128k $fn_out

    echo "End of iteration"
    echo
    done
echo "Script completed"

注釋掉 ffmpeg 行,以及 ./TBC 目錄中的兩個文件,這是我得到的輸出

    Start of iteration
    Full text of file name: ./TBC/Test file with spaces.mp4
    Original filename: Test file with spaces.mp4
    Filename Length: 25
    Base filename: Test file with spaces
    Converted file name: ./CONV/Test file with spaces.conv.mp4
    End of iteration

    Start of iteration
    Full text of file name: ./TBC/Test_file_with_NO_spaces.mp4
    Original file name: Test_file_with_NO_spaces.mp4
    Filename Length: 28
    Base file name: Test_file_with_NO_spaces
    Converted file name: ./CONV/Test_file_with_NO_spaces.conv.mp4
    End of iteration

    Script completed

當 ffmpeg 未注釋時,我不會費心發布結果,除了聲明它失敗並出現錯誤:./TBC/Test: No such file or directory

然后腳本繼續到下一個成功完成的文件,因為它的名稱中沒有空格。 實際文件名是“Test file with spaces.mp4”,因此您可以看到 ffmpeg 在遇到空格時在“Test”一詞之后停止。

我希望這是清晰簡潔的,希望有人能夠為我指明正確的方向。 我還想用這個腳本做很多事情,比如解析子目錄和忽略非視頻文件等。

我期待您提供任何見解!

嘗試引用輸出文件:

ffmpeg -i "$file" ... "$fn_out"

bash基於空格分隔參數,因此您必須告訴他$ fn_out是一個參數。 “”表示這是一個參數。

還有另一種極端情況,空格會破壞 bash for 循環。

“在處理文件集時,BASH for 循環在 UNIX/Linux/Windows 和 OS X 下工作得很好。但是,如果您嘗試在文件名中處理帶有空格的 for 循環,您將遇到一些問題。for 循環使用$IFS 變量來確定字段分隔符是什么。默認情況下 $IFS 設置為空格字符..."

https://www.cyberciti.biz/tips/handling-filenames-with-spaces-in-bash.html

前:

for file in $(find . -name '*.txt'); do echo "$file"; done

輸出:

./files/my
documents/item1.txt
./files/my
documents/item2.txt
./files/my
documents/item3.txt

因此,您應該將 IFS 設置為忽略空格。

后:

IFS=$'\n'
for file in $(find . -name '*.txt'); do echo "$file"; done

輸出:

./files/my documents/item1.txt
./files/my documents/item2.txt
./files/my documents/item3.txt

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM