我有一个包含这些文件列表的文件夹。
lesson1.mp4
lesson2.mp4
lesson3.mp4
lesson4.mp4
我正在尝试根据“rename.txt”的内容重命名此文件
1. Introduction to the React Ecosystem Video
2. Video Babel, Webpack, and React
3. Solution - Props
4. Solution - .map and .filter
我正在运行这个脚本
for file in *.mp4;
do read line;
mv -v "${file}" "${line}";
done < rename.txt
这给了我不想要的结果
'lesson1.mp4' -> '1. Introduction to the React Ecosystem Video '
'lesson10.mp4' -> '2. Video Babel, Webpack, and React '
'lesson11.mp4' -> '3. Solution - Props '
'lesson12.mp4' -> '4. Solution - .map and .filter '
'lesson13.mp4' -> '5. Video Validating Components with PropTypes'
想要的结果。
'lesson1.mp4' -> '1. Introduction to the React Ecosystem Video.mp4'
'lesson2.mp4' -> '2. Video Babel, Webpack, and React.mp4'
'lesson3.mp4' -> '3. Solution - Props.mp4'
'lesson4.mp4' -> '4. Solution - .map and .filter.mp4'
'lesson5.mp4' -> '5. Video Validating Components with PropTypes.mp4'
答案1
您可以使用 shell 扩展而不是通配符:
for file in lesson{1..10}.mp4;do
read line
mv -v "${file}" "${line}"
done < rename.txt
虽然这看起来很容易出错,但如果您有很多文件需要执行此操作,您可以查看将文件名中的数字与重命名文件中行开头的数字进行匹配。就像是:
for file in *.mp4;do
num=$(echo "${file}" | sed -E 's/^lesson([0-9]+).mp4$/\1/')
line=$(grep -E "^ *${num}\." rename.txt)
mv -v "${file}" "${line}"
done
这样,文件的顺序就无关紧要rename.txt
,shell 全局文件名的顺序也无关紧要。
答案2
此答案使用-v
选项来ls
保证文件列表的正确数字排序。每个文件名都放在 shell 位置参数中。为了保证每个参数中都包含完整的文件名,它会暂时更改 shell 的“内部字段分隔符”,这样,如果您最终的文件名中包含嵌入空格,它仍然可以工作。最后,因为我讨厌带有嵌入空格的文件名(并且您最好培养类似的本能),所以它将所有嵌入空格转换为下划线。该shift
命令只是向前弹出所有位置参数的值,因此$1
获取列表中的下一个值。
oldifs="${IFS}"
IFS=$'\n'
set $(ls -v1 lesson*)
while read line ; do
mv "$1" "${line// /_}"
shift
done < rename.txt
IFS="${oldifs}"