将文件名的最后部分移到前面

将文件名的最后部分移到前面

我有几个这样命名的文件: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"

相关内容