mcE*_*nge 5 bash shell-script ascii unicode
我下载了许多 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
Run Code Online (Sandbox Code Playgroud)
由于文件名中的特殊字符,上述功能不起作用。
以下是一些示例文件名:
??? (Stomach) ?? ???? ?? ??? 5 ??? ???-3G4pEY5njYE.mp4
?? ???? ???? ?? ??? ??? ???????? ??? _ ?????? ??????-sPytQlaxoIg.mp4
???????? ???? ?? ????? ?? ????? _ Swami Ramdev-A-2d04ON9hA.mp4
Run Code Online (Sandbox Code Playgroud)
奖励:
我也希望在打印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
Run Code Online (Sandbox Code Playgroud)
请注意,上面的代码将在当前目录中生成符号链接。如果您第二次运行它,它会选择这些链接并创建指向这些符号链接的更多链接。最好在单独的目录中创建链接,更小心地使用与循环一起使用的文件名通配模式以避免链接,或者显式测试循环中的链接并跳过这些链接。
counter=0
for video in ./*; do
[ -L "$video" ] && continue # skip symbolic links
counter=$(( counter + 1 ))
ln -s -- "$video" "link_name_$counter.mp4"
done
Run Code Online (Sandbox Code Playgroud)
要获得四位数的零填充计数器,您可以使用
printf -v zcounter '%.4d' "$counter"
Run Code Online (Sandbox Code Playgroud)
这会将重新格式化的计数器直接打印到zcounter
变量。然后您将在生成文件名时使用该变量。或者您可以通过这种方式一次性生成符号链接的名称:
printf -v zcounter '%.4d' "$counter"
Run Code Online (Sandbox Code Playgroud)
也可以看看:
归档时间: |
|
查看次数: |
349 次 |
最近记录: |