在开头以特定模式更改目录中的文件名

change file names in a directory with a certain pattern at the beginning

我想从一个目录中的文件名中删除数字:

文件名:

89_Ajohn_text_phones
3_jpegs_directory
..

我想要什么

Ajohn_text_phones
jpegs_directory

我试过了:

rename 's/^\([0-9]|[0-9][0-9]\)_//g' *

但是我没有工作。

有两个 rename 工具。您似乎尝试使用的是基于 Perl 的,因此使用 perl 样式的正则表达式。转义规则与 sed 略有不同;特别是,用于分组的括号不会转义(转义的括号是文字括号)。使用

rename 's/^([0-9]|[0-9][0-9])_//' *

或者,更简洁一点,

rename 's/^[0-9]{1,2}_//' *

rename 是基于 Debian 的发行版的默认设置,例如 Ubuntu。

另一个 rename 工具来自 util-linux,它是一个非常简单的工具,不能与正则表达式一起使用,无法满足这一特殊要求。例如,它是基于 Fedora 的发行版的默认设置,更糟糕的是,那些通常甚至不打包 Perl 重命名。您可以在 CPAN 上找到 Perl 重命名 here 并根据需要将其放入 /usr/local/bin,但除此之外,您最简单的选择可能是 shell 循环 mvsed:

for f in *; do
    # set dest to the target file name
    # Note: using sed's extended regex syntax (-r) because it is nice.
    #       Much less escaping of metacharacters is needed. Note that
    #       sed on FreeBSD and Mac OS X uses -E instead of -r, so there
    #       you'd have to change that or use regular syntax, in which
    #       the regex would have to be written as ^[0-9]\{1,2\}_
    dest="$(echo "$f" | sed -r 's/^[0-9]{1,2}_//')"
    if [ "$f" = "$dest" ]; then
        # $f did not match pattern; do nothing
        true;
    elif [ -e "$dest" ]; then
        # avoid losing files.
        echo "$dest already exists!"
    else
        mv "$f" "$dest"
    fi
done

您可以将其放入 shell 脚本中,比如 rename.sh:

#!/bin/sh

transform=""
shift

for f in "$@"; do
    dest="$(echo "$f" | sed -r "$transform")"
    if [ "$f" = "$dest" ]; then
        ## do nothing
        true;
    elif [ -e "$dest" ]; then
        echo "$dest already exists!"
    else
        mv "$f" "$dest"
    fi
done

并调用 rename.sh 's/^[0-9]{1,2}_//' *.

还有一个警告:在

dest="$(echo "$f" | sed -r "$transform")"

"$f" 有可能是 echo 认为的命令行选项,例如 -n-e。我不知道有什么方法可以解决这个问题(如果你读过这篇文章并且知道一个,请发表评论),但是如果你处于 bash 束缚自己不成问题的位置,你可以使用 bash 的字符串改为:

dest="$(sed -r "$transform" <<< "$f")"

(并将 #!/bin/sh shebang 替换为 #!/bin/bash)。不过,这样的文件很少见,所以随着定时炸弹的流逝,这不太可能是哑弹。

#!/bin/bash
for f in *
do
  mv "$f" "${f#*_}"
done