采用可变长度文件名“abcdef - ghijkl.pdf”并将其重命名为“ghijkl - abcdef.pdf”
如何在命令行脚本中为单个文件夹中的所有文件实现这一点?
答案1
由于你使用的是 Ubuntu,你应该至少有一个基于 perl 的rename
或prename
$ rename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
rename(abcdef - ghijkl.pdf, ghijkl - abcdef.pdf)
$ prename -n -- 's/(\w*) - (\w*)/$2 - $1/' *.pdf
abcdef - ghijkl.pdf renamed as ghijkl - abcdef.pdf
或者,您可以安装并使用mmv
$ mmv -n '* - *.pdf' '#2 - #1.pdf'
abcdef - ghijkl.pdf -> ghijkl - abcdef.pdf
(在所有情况下,删除-n
才能实际完成操作)。
答案2
使用bash:
[[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] &&
mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"
这使用 bash 的正则表达式测试运算=~
符来查看给定的文件名(在 中$f
)是否与模式匹配:“除破折号之外的任何内容,后跟空格破折号空格,后跟除句点之外的任何内容,后跟句点,后跟任何内容” 。如果文件名与该模式匹配,则正则表达式括号内的子部分的匹配位将分配给 BASH_REMATCH 数组的元素。
要对特定文件夹中的每个文件执行此操作:
cd /to/that/folder
for f in *
do
[ -f "$f" ] || continue
[[ $f =~ ^([^-]+)\ -\ ([^\.]+)\.(.*) ]] &&
mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}.${BASH_REMATCH[3]}"
done
仅使用POSIX 指定的变量扩展:
pre=${f%%.*}
ext=${f##*.}
mv "$f" "${pre##*- } - ${pre%% -*}.$ext"
答案3
您可以使用该命令创建脚本:
\ls *-*.pdf | sed 's/\(.*\)-\(.*\).pdf/mv \1-\2.pdf \2-\1.pdf/' > script_mv.bash
然后检查脚本是否正确,然后可以执行它:
. ./script_mv.bash
我写了 \ls,因为它取消了 ls 上的选项。
sed 模式的含义是:
- 找到任何内容1、“-”、任何内容2、“.pdf”。
- 这两个内容都包含在 ( ) 中,以便它们获得名称 \1 和 \2 。
- 然后我复制 mv 行,因为 \1 和 \2 ,我可以重新创建文件名。
答案4
害羞的答案,具体到“xxx - yyyy.ddd”名称模式。
find -type f | while read flnm ; do basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}'; done
找到一个文件并将名称交给 while read 循环。在那里,使用 basename 提取名称并将其交给 Awk。 awk 使用多个字段分隔符、空格和句点,然后以所需的顺序重新打印字段。
abcdef - ghijkl.pdf
变成
ghijkl - abcdef.pdf
实际应用...将文件重命名为这个新的模式名称
find -type f | while read flnm ; do mv "$(basename "$flnm")" "$(basename "$flnm" | awk -F'[\ .]' '{print $3 " " $2 " " $1 "."$4}')"; done
唯一的区别是包含 mv 命令并将名称包装为字符串。