我有几个这样命名的文件:This is a test - AB12-1998.avi
(最后一个代码始终为 2 个字母、2 个数字、短划线、4 个数字)
我想做的就是像这样重命名它们:AB12-1998 - This is a test.avi
我很感激您可以使用 bash、重命名或任何其他方式为我提供任何解决方案,只要它能完成工作即可。
答案1
使用 Perl rename
(*):
rename 's/^(.*) - (.*)(\..*)$/$2 - $1$3/' *.avi
或者,如果您想对代码更严格:
rename 's/^(.*) - ([a-zA-Z]{2}\d{2}-\d{4})(\..*)$/$2 - $1$3/' *.avi
即使对于像这样的名称也应该有效foo - bar - AB12-1234.avi
,因为第一个.*
贪婪地匹配最后一个<space><dash><space>
。
(* 看:所有重命名是怎么回事:预命名、重命名、文件重命名?)
或者在 Bash 中类似:
for f in *.avi ; do
if [[ "$f" =~ ^(.*)\ -\ (.*)(\..*)$ ]]; then
mv "$f" "${BASH_REMATCH[2]} - ${BASH_REMATCH[1]}${BASH_REMATCH[3]}"
fi
done
简而言之,正则表达式分解为
^ start of string
( ) capture group
.* any amount of anything
\. a literal dot
$ end of string
大多数常规字符都与自身匹配,尽管您需要在 Bash 中使用反斜杠转义空格(如上所述)。捕获组的内容在Perl 中按$1
、等顺序出现,在 Bash 中按、等顺序出现。$2
${BASH_REMATCH[1]}
${BASH_REMATCH[2]}
答案2
使用/bin/sh
:
for name in *.avi; do
n=${name%.avi} # name without filename extension
first=${n%% - *} # first part of name
last=${n#* - } # last part of name
new="$last - $first.avi" # recombined new name
printf 'Would move "%s" to "%s"\n' "$name" "$new"
# mv -- "$name" "$new"
done
删除中${parameter%%word}
匹配的最长后缀字符串,同时删除中匹配的最短前缀字符串。因此,代码将在第一次出现(space-dash-space)时交换两个子字符串。word
$parameter
${parameter#word}
word
$parameter
-
删除推荐的内容mv
以实际重命名文件。
在评论中伊尔卡丘的回答,我看到您也想交换名称的第一部分,这样就AB12-1998
变成了1998-AB12
。
由于我们现在对名称进行两次交换操作,因此我们可以将其放入一个函数中:
swap () {
# swaps the two part of a string around
# the swap point is defined by the first argument
swstr=$1
string=$2
first=${string%%$swstr*}
last=${string#*$swstr}
printf '%s%s%s\n' "$last" "$swstr" "$first"
}
for name in *.avi; do
n=${name%.avi}
n=$( swap ' - ' "$n" )
first=${n%% - *}
first=$( swap '-' "$first" )
new="$first - ${n#* - }.avi"
printf 'Would move "%s" to "%s"\n' "$name" "$new"
# mv -- "$name" "$new"
done
输出示例:
Would move "This is a test - AB9-1995.avi" to "1995-AB9 - This is a test.avi"
Would move "This is a test - AB9-1996.avi" to "1996-AB9 - This is a test.avi"
Would move "This is a test - AB9-1997.avi" to "1997-AB9 - This is a test.avi"
Would move "This is a test - AB9-1998.avi" to "1998-AB9 - This is a test.avi"
Would move "This is a test - AB9-1999.avi" to "1999-AB9 - This is a test.avi"