Bash

如何處理 bash 腳本中包含阿拉伯文、中文、印地文字元的“YouTube 文件名”?

  • May 23, 2020

我下載了許多 YouTube 影片並想使用bash腳本處理它們。但是,使用的文件名包含各種特殊字元和非 ASCII 字元。

我如何在bash腳本中處理這個?

假設我想為文件夾中的每個此類文件創建一個符號連結:

# Write filenames to filelist.txt in parent folder
ls ./* > ../filelist.txt

# Create sym links for all files in filelist.txt
counter=0
while read video_name; 
 do 
 counter=$((counter+1)); 

 ln -s $video_name  link_name_${counter}.mp4

done < ../filelist.txt

由於文件名中的特殊字元,上述功能不起作用。

以下是一些範例文件名:

पेट (Stomach) कम करने के लिए  5 योग आसन-3G4pEY5njYE.mp4
मन शांत करने के लिए करे वृक्षासन योग _ स्वामी रामदेव-sPytQlaxoIg.mp4
वृक्षासन करने का तरीका और फायदे _ Swami Ramdev-A-2d04ON9hA.mp4

獎勵:

我也希望在列印counter變數時使用“前導零”,但這並不重要。

shell 中的變數可以包含任何字元,除了 NUL 字元,就像文件系統中的文件名一樣。因此,將文件名儲存在變數中應該不會有任何問題,除非您讀取 的損壞輸出ls,可能會出於顯示目的而對其進行修改(ls輸出僅用於查看)。

在編輯後的問題中,您還從文本文件中讀取了文件名,read預設值為$IFS(這決定了工作方式的各個方面read)。這將從文件中讀取的行中去除側翼空格,並且\如果該字元出現在輸入中,則可以對其進行特殊解釋。另請注意,從技術上講,文件名可能包含換行符,因此將它們儲存為以換行符分隔的列表(文本文件中的行)會限制可以使用的名稱類型。

您還需要引用擴展變數。您的文件名中包含空格,並且不引用該$video值,shell 會將它們拆分為多個單詞,並將這些單詞(在使用這些作為模式另外執行文件名通配之後)作為單獨的參數提供給ln -s.

不要ls用於生成文件名列表,並引用所有變數的擴展:

counter=0

for video in ./*; do
   counter=$(( counter + 1 ))
   ln -s -- "$video" "link_name_$counter.mp4"
done

請注意,上面的程式碼將在目前目錄中生成符號連結。如果您第二次執行此程序,它將獲取這些連結並創建指向這些符號連結的更多連結。最好在單獨的目錄中創建連結,更加小心循環使用的文件名通配模式以避免連結,或者明確測試循環中的連結並跳過這些。

counter=0

for video in ./*; do
   [ -L "$video" ] && continue    # skip symbolic links
   counter=$(( counter + 1 ))
   ln -s -- "$video" "link_name_$counter.mp4"
done

要獲得一個四位數的零填充計數器,您可以使用

printf -v zcounter '%.4d' "$counter"

這會將重新格式化的計數器直接列印到zcounter變數中。然後,您將使用該變數生成文件名。或者您可以通過這種方式一次性生成符號連結的名稱:

counter=0

for video in ./*; do
   [ -L "$video" ] && continue    # skip symbolic links
   counter=$(( counter + 1 ))

   printf -v linkname 'link_name_%.4d.md4' "$counter"
   ln -s -- "$video" "$linkname"
done

也可以看看:

引用自:https://unix.stackexchange.com/questions/588464