[英]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.