使用重命名命令重命名单个文件,忽略文件扩展名

使用重命名命令重命名单个文件,忽略文件扩展名

这将重命名所有扩展名为 jpg 的文件。

rename 'y/a-z/A-Z/' *.jpg

这将重命名该文件,但也会重命名扩展名。

rename 'y/a-z/A-Z/' image.jpg

如何在不改变扩展名的情况下重命名单个文件?

example.jpg

输出应该是:

EXAMPLE.jpg

答案1

改名

rename  -n 's/.*\./\U$&/'
  • -n争论是为了不做出改变并告诉你将会发生什么。
  • .*正则表达式世界中的参数是 select一切,与 一起使用\.是选择点之前的所有内容[.] ⇾.*\.选择点之前的所有内容。
    • 使用\[反斜杠] 转义字符,因为.[点] 在正则表达式
  • \Uargument 表示大写直到,这是一个转义序列在Perl正则表达式中,它必须与\[反斜杠]一起使用
  • $&参数用于查找上次成功模式搜索中匹配的字符串。示例/find/$&ADD/返回:findADD
返回:
rename(fellowSHIP.jpg, FELLOWSHIP.jpg)
rename(retorno2.jpg, RETORNO2.jpg)
rename(retorno3.jpg, RETORNO3.jpg)
rename(retorno4.jpg, RETORNO4.jpg)
rename(shein1.jpg, SHEIN1.jpg)
rename(shein2.jpg, SHEIN2.jpg)
rename(shein3.jpg, SHEIN3.jpg)
rename(shein4.jpg, SHEIN4.jpg)
rename(shein-girl1.jpg, SHEIN-GIRL1.jpg)
rename(sheingirl2.jpg, SHEINGIRL2.jpg)
rename(twoTowers1.jpg, TWOTOWERS1.jpg)
rename(twoTowers2.jpg, TWOTOWERS2.jpg)
rename(twoTowers3.jpg, TWOTOWERS3.jpg)
rename(twoTowers4.jpg, TWOTOWERS4.jpg)
rename(twoTowers5.jpg, TWOTOWERS5.jpg)
rename(twoTowers6.jpg, TWOTOWERS6.jpg)


答案2

rename 's/(.*)(\.[^.]+)/\U$1\E$2/' example.jpg
  • s/开始替换
  • (.*)匹配后缀之前的文件名部分(任何字符,任何数量),在第一组中捕获
  • (\.[^.]+)匹配后缀,a.后跟一个或多个非.字符,在第二组中捕获
  • /开始更换
  • \U大写(直到\E
  • $1插入第一个匹配组
  • \E最终情况修改
  • $2插入第二个匹配组
  • /末端替换

答案3

请注意(除了 中不相关且非常有限的一个util-linux)现在有一些 perlrename命令的变体(最初是perl3.0附带的一个非常短的示例脚本)。

与来自https://metacpan.org/dist/File-Rename并在最近基于 Debian 的系统上的软件包中找到rename,要将任意文件名中的所有 ASCII 字母转为大写,但扩展名中不转为大写(如果有),您可以执行以下操作:

rename -d -- 's/.*\.|.*/\U$&/s' "$file"

在哪里:

  • -d确保文件的目录名不受影响。
  • --该实现需要,否则将采用$file开头-作为选项(--e=exec("rm -rf ~")例如,对于调用的文件会产生灾难性的后果)。
  • 需要 ubstitutes的标志,否则将不会匹配换行符(与文件名中的任何字符一样有效的字符)。s.
  • .*\.|.*匹配最右边的任何内容.(如.*贪婪)或所有内容,请记住,perl首先尝试左侧模式并且与 POSIX 正则表达式相反,不会尝试查看另一个模式是否会产生更长的匹配。因此,对于有扩展名的文件,它将匹配扩展名之前的内容;对于没有扩展名的文件,它将匹配整个文件名。
  • $&是匹配的内容。以 为前缀\U,会被转换为大写,就像在ex/viperl借用的一样。

示例-n(用于试运行):

$ rename -n -d -- 's/.*\.|.*/\U$&/s' $'--e=system("echo reboot") #/foo\nbar.jpg'
rename(--e=system("echo reboot") #/foo
bar.jpg, --e=system("echo reboot") #/FOO
BAR.jpg)
$ rename -n -d -- 's/.*\.|.*/\U$&/s' .config/gtkrc
rename(.config/gtkrc, .config/GTKRC)
$ rename -n -d -- 's/.*\.|.*/\U$&/s' .bashrc
$

(在.bashrc这里,bashrc被视为扩展)。

现在,一个问题是它仅适用于 ASCII 文件名。

例如,它会将 UTF-8 转换Stéphane.jpgSTéPHANE.jpg而不是STÉPHANE.jpg(至少é在预组合形式的情况下)或更糟糕地将 BIG5-HKSCS 转换Stéphane.jpgSt<U+F310>phane.jpg.

解决这个问题rename有点痛苦。你需要类似的东西:

rename -n  -d -- '
  use Encode::Locale;
  use Encode;

  $_ = decode(locale_fs => $_);
  s/.*\.|.*/\U$&/s;
  $_ = encode(locale_fs => $_)' "$file"

将文件视为使用区域设置的字符集进行编码。

但请注意,它会将无法解码为字符的字节转换为某些替换字符(类似于?取决于语言环境;在 C 语言环境中,包括高于 127 的所有字节值)。

最后,使用 shell 的操作符可能会更容易、更安全。像zsh

case $file:t in
  (*.*) newfile=$file:h/$file:t:r:u.$file:e;;
  (*) newfile=$file:h/$file:t:u;;
esac
[[ $file = $newfile ]] || mv -i -- $file $newfile

(其中:t:h:r:e:u是 csh 风格的修饰符,分别产生tail、head、rootname、extension 和 Turn 为uppercase)。

zsh的运算符将尽最大努力:转换可以解码的字符,而保留无法解码的字节序列。

zsh还有它自己的内置批量重命名工具:zmv,作为自动加载函数实现:

autoload -Uz zmv # best in ~/.zshrc
zmv '(*).(*)' '$1:u.$2'

(仅重命名具有扩展名的非隐藏文件)

zmv在开始重命名之前还会进行一些健全性检查,这也使其比rename.

相关内容