这真是一团糟。当我们期望 Perl 使用s///
类似 sed 的语法重命名时,当有大量不同的 实现rename
,并且大多数情况下是 Perl 的不同版本rename.ul
(二进制)时,我如何知道使用哪个命令?
答案1
珀尔的rename
用于批量重命名文件的最著名、最直观的工具是 Perl 的rename
.它非常类似于sed
类固醇(但用于重命名文件)。
长话短说
如果你想按预期的方式使用它,最好使用 Perl 的 CPAN 安装预期的版本。那里有太多版本。
请参阅下面的“通用 Perl CPAN 安装”。
用法(sed
s///
如)
它能够进行强大的正则表达式处理:
rename [options] 's/<regex>/<replacement>/[modifiers]' <FILE(S)>[*]
<STDIN> | rename [options] 's/<regex>/<replacement>/[modifiers]'
例子
如果要在
TitleCase
(中的 mp4 文件名的每个单词之间添加空格PascalCase
到用空格分隔的单词):rename -n 's/\B[[:upper:]]/ $&/g' ./*.mp4 rename(./FooBarBaz.mp4, ./Foo Bar Baz.mp4)
删除
-n
开关,也就是dry-run
当您的尝试令人满意时重命名为真实的。您甚至可以在该
replacement
部分中注入调用,例如sprintf "%03d", 7
使用修饰符进行零填充e
:$ touch {1..3}.txt $ rename -n 's/(\d+)\.txt/sprintf "%03d", $1/e' ./*.txt rename(1.txt, 001.txt) rename(2.txt, 002.txt) rename(3.txt, 003.txt)
-
通过使用分隔的文本的相反顺序捕获组:$ rename -n 's/(\w+)-(\w+)-(\w+)/$3-$2-$1/' ./foo-bar-base.txt rename(foo-bar-base.txt, base-bar-foo.txt)
或使用
Perl
这样的方式(TMTOWTDI):$ rename -n 's/(\w+)-(\w+)-(\w+) # capture groups /join "-", reverse @{^CAPTURE}/xe' foo-bar-base.txt rename(foo-bar-base.txt, base-bar-foo.txt)
花时间去掌握 Perl 是值得的。但是,要开始使用 rename 命令的省时功能,您根本不需要具备太多 Perl 知识,即可在功能、简单性和时间方面获得巨大优势。
检查你自己的版本
某些发行版上还使用了另一个同名的二进制工具。根据您的发行版,Perl 版本可以称为perl-rename
, file-rename
, prename
,pname
或者rename
。
还有一个Pythonrename
指挥在那里!
rename --version
应该看起来像这样:
/usr/bin/rename using File::Rename version 1.30, File::Rename::Options version 1.10
或者在旧版本上:
Unknown option: help
Usage: rename [-v] [-n] [-f] perlexpr [filenames
或者
rename 2>&1 | grep -i perl
[ -e|-E perlexpr]*|perlexpr [ files ]
而不是使用的东西 rename
从util-linux
rename 命令的默认版本与发行版表
借自@mebeim 对 tldr-pages 的 GitHub 问题跟踪器的评论:
珀尔(旧) Perl(新) Perl(其他?) C Linux(Debian) 名称 (pkg perl),已弃用 文件重命名(pkg 重命名) 不适用 rename.ul(pkg util-linux) Linux(Ubuntu) 不适用 文件重命名(pkg 重命名) 不适用 rename.ul(pkg util-linux) Linux(架构) 不适用 不适用 perl 重命名 (pkg perl 重命名) 重命名(pkg util-linux) Linux(CentOS、RHEL) 不适用 不适用 不适用 重命名(pkg util-linux) Linux(软呢帽) 不适用 不适用 名字(pkg 名字) 重命名(pkg util-linux) Linux(openSUSE) 不适用 不适用 不适用 重命名(pkg util-linux) macOS(自制) 不适用 不适用 重命名(包重命名) 重命名(pkg util-linux) 视窗 不适用 不适用 不适用 不适用 索拉里斯 不适用 不适用 不适用 不适用
重要笔记:
在 Windows 上,
rename
是一个完全不同的命令(因此我没有在上面列出),但也可以使用,请检查如何在 Windows 上使用 Perl 的重命名在 Solaris 上,不
rename
存在命令在 macOS 上,Homebrew 软件包
rename
和util-linux
冲突在 macOS 上,Homebrew 软件包
rename
提供了一个看起来与其他脚本不同的 Perl 脚本在 Arch Linux 上,该
perl-rename
软件包提供了一个与其他脚本不同的 Perl 脚本在 Feroda 上,
prename
提供了一个与其他脚本不同的 Perl 脚本在 Debian 上,
prename
并且file-rename
是替代品rename
在 Ubuntu 上,
file-rename
是唯一的选择rename
姆克什有一个内置的
rename
.要使用 Perl 的rename
,必须使用完整路径:/usr/bin/rename
,或定义一个alias rename=/usr/bin/rename
CPAN
使用或不使用 root 权限进行通用 Perl安装
我推荐这种方式,因为周围有太多不同的版本。这样,您就可以准确地知道您将拥有哪个版本。
- 使用
cpan -i File::Rename
(更好地使用Perl 酿造对于普通用户)。该rename
命令将可用。如果没有,则您的PATH
不包含 Perl 脚本实用程序。 - for
Debian*
,用于dh-make-perl --build --cpan File::Rename
制作 Debian 软件包
如果您无法安装任何东西,下载它作为独立脚本(简化的旧版本,没有依赖项(除了perl
)并且比新版本更少的开关)
映射rename
VS 发行版(如果不是好的发行版)
如果您更喜欢系统包管理器:
这是 Debian(替代)操作系统上的默认rename
命令(与 Arch Linux、rpm
基于发行版、Slackware 和 *BSD 不同)。
rpm
基于的发行版:dnf install prename
Arch Linux/Manjaro:
pacman -S perl-rename
根图:
emerge dev-perl/rename
NixO:
nix-env -i perl5.36.0-rename nix-env -iA nixos.perlRename
这是不是推荐的方式对于纯粹主义者来说。
*BSD:
pkg install p5-File-Rename
Alpine Linux(在存储库
edge
的分支中testing
,默认情况下不使用):apk add perl-file-rename --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/
苹果系统:
brew install rename
类似 Debian/Ubuntu:
apt install rename
松弛软件:
slackbuild
文档
- 查看Perl 的关于重命名的文档
- perldoc perle#字符类是理解短裤的必读页面
\d
,\w
\s
...(PCRE、Perl、Python、PHP)
统一码
还有一个特定的 Unicoderename
实现:Unicode::Tussle
如果您的文件包含连续的 Unicode UTF8 字符,例如AaaÃééZzz.mp4
Unicode 部分将被忽略。一种解决方案是使用特殊开关unicode
:
-u, --unicode [编码]
运行用户提供的代码时,将文件名视为 perl (unicode) 字符串。
使用编码对文件名进行解码/编码(如果存在)。
编码是可选的:如果省略,下一个参数应该是以“-”开头的选项,例如-e。
或者如果您有一个没有的(旧)版本-u
,您可以执行以下操作:
PERL_UNICODE=ASD rename -n 's/\B\p{Lu}/ $&/g' ./*.mp4
查看
perldoc perlrun | less +/PERL_UNICODE
安全
为避免可能外壳注入(谢谢@斯蒂芬·查泽拉斯):
rename -n 's/.*//' '--e=system"uname"#.mp4'
Linux
养成使用习惯:(最便携)
rename -n 's/.*//' ./*
或者如果支持:
rename -n 's/.*//' -- *
既可以防止外壳注入并将以开头的文件视为-
开关。
尝试重命名文件,例如rename -n 's/.*//' -foobar.txt