批量重命名文件
Posted
技术标签:
【中文标题】批量重命名文件【英文标题】:Batch rename files 【发布时间】:2013-09-15 14:25:56 【问题描述】:我想批量重命名目录中的多个文件,以便从文件名中去除前面的数字和连字符。
Old file name: 2904495-XXX_01_xxxx_20130730235001_00000000.NEW
New file name: XXX_01_xxxx_20130730235001_00000000.NEW
如何使用 linux 命令执行此操作?
【问题讨论】:
Renaming files in bash 的可能重复项 【参考方案1】:这应该可以:
rename 's/^[0-9]*-//;' *
它从开头多次获取块[0-9]
(即数字),然后是连字符-
,并将其从文件名中删除。
如果rename
不在您的机器中,您可以使用循环和mv
:
mv "$f" "$f#[0-9]*-"
测试
$ ls
23-aa hello aaa23-aa
$ rename 's/^[0-9]*-//;' *
$ ls
aa hello aaa23-aa
或者:
$ ls
23-a aa23-a hello
$ for f in *;
> do
> mv "$f" "$f#[0-9]*-"
> done
$ ls
a aa23-a hello
【讨论】:
这不适用于我的rename
版本(util-linux-ng 2.17.2)。你用的是什么版本?
rename 在 Fedora 和 Debian 版本的 util-linux 中,但在 OSX 上似乎默认不包含。
@Yossarian 检查我更新的答案,使用mv
。对你有用吗?
是的,mv
命令对我有用。似乎必须有两个版本的rename
- 我的需要三个参数(rename from to file
)。
@cjungel 不确定你的意思【参考方案2】:
如果第一个数字总是相同的长度:
for F in *new ; do
mv $F $F:8
done
$parameter:number
进行子字符串扩展 - 获取从第 8 个字符开始的字符串。
扩展中还有许多其他字符串编辑可用于处理其他情况。
【讨论】:
【参考方案3】:使用renamer(Windows、Mac 和 Linux 友好):
$ renamer --find '/\d+-(.*)/' --replace '$1' *
这将删除当前目录中所有文件开头的所有数字和第一个连字符。
【讨论】:
是否可以安装依赖项? 我不确定你的意思。renamer site 上有安装说明。这有帮助吗? node 包管理器似乎存在包依赖问题,所以它没有只安装一个命令,而且 npm 也没有在自动模式下安装依赖。 我刚刚运行npm install -g renamer
- 它安装正确并且工作正常.. 请确保您安装了最新的node.js.. 如果您仍然遇到问题,请提出问题here
【参考方案4】:
我认为如果你执行下面的命令,这个命令会更好:
ls * | sed -e 'p;s/old-name/new-name/' | xargs -n2 mv
这里 ls * - 列出当前文件夹中的文件sed -e - 执行表达式p; - 打印旧文件名 s/old-name/new-name/ - 生成新文件名 xargs -n2 - 处理 mv 的两个参数mv - 获取两个参数并进行移动操作
建议:在执行 mv 之前验证您所做的是您想要通过 echo 实现的目标。
ls * | sed -e 'p;s/old-name/new-name/' | xargs -n2 echo
以下示例重命名
SCCF099_FG.gz5329223404623884757.tmp 到 SCCF099_FG.gz
ls *tmp | sed -e 'p;s/\([0-9]\)\+\.tmp/ /g' | xargs -n2 echo
ls *tmp | sed -e 'p;s/\([0-9]\)\+\.tmp/ /g' | xargs -n2 mv
【讨论】:
超级有帮助。谢谢! 我看到这是旧的;但是你能分解一下这条线发生了什么吗?这是我的理解:在对sed
的调用中,如果说存在5 个文件,则表达式字符串会打印每一行,然后在下面立即打印其查找和替换的副本;然后,xargs
现在每次 2 次解析 10 个项目 的列表,并将它们作为参数传递给 mv
。对吗?
我用于包含空格的文件名的细微变化:find . -print0 | sed -z -e 'p;s/old-name/new-name/' | xargs -n2 -0 mv
.【参考方案5】:
这可能看起来有点复杂,但它非常有效,并且在 *nix 和 OSX 系统上都运行良好。它还递归地执行,重命名当前目录以及任何子目录中的文件:
find . -regex '.*/[0-9]\7\[-].*' -print > temp1 && \
cp temp1 temp2 && \
vi -c ":g/\([0-9]\7\[-]\)\(.*\)/s//\2/" -c ":x" temp2 && \
paste temp1 temp2 > temp3 && \
vi -c ":g/^/s//mv /" -c ":x" temp3 && \
sh ./temp3 && \
rm temp1 temp2 temp3
以下是刚刚发生的事情的细分:
第一行表示查找 (find
) 所有文件,从当前目录 (.
) 中的文件开始,其名称与 "7 个数字的模式 (-regex
) 匹配,后跟一个破折号,后跟 0 个或多个字符” ('.*/[0-9]\7\[-].*'
),然后将这些文件名及其各自的路径 (-print
) 写入名为 temp1 (> temp1
) 的文件中。请注意,-print
指令在大多数情况下可能不是必需的,但它不会造成任何伤害。
find . -regex '.*/[0-9]\7\[-].*' -print > temp1 && \
然后,将 temp1 的内容复制 (cp
) 到名为 temp2 的文件中。
cp temp1 temp2 && \
接下来,使用 vi text editor 打开文件 temp2 并给 vi 两个命令(使用 -c
表示每个新命令):
-
命令 #1:
在 temp2 (
:g
) 的每一行中搜索我们在上面搜索的相同模式,但这次使用括号 (\([0-9]\7\[-]\)\(.*\)
) 对结果进行分组。
对于每个匹配行,将光标移动到找到匹配项的位置,然后仅将整个匹配项替换为匹配模式的第二组 (\2
)。
命令 #2:
保存对 temp2 所做的更改并关闭文件 (:x
)。
结果是这样的:
vi -c ":g/\([0-9]\7\[-]\)\(.*\)/s//\2/" -c ":x" temp2 && \
现在,将 temp1 中的行与 temp2 (paste
) 中的行连接起来,并将每个新组合的行写入一个名为 temp3 (> temp3
)。
paste temp1 temp2 > temp3 && \
接下来,再次运行 vi,执行与上述相同的步骤,只是这次在文件 temp3 中搜索每一行的开头 (^
) 并添加mv 和紧随其后的一个空格 (mv
)。
vi -c ":g/^/s//mv /" -c ":x" temp3 && \
然后,将 temp3 (./temp3
) 的内容作为 shell 脚本 (sh
) 执行。
sh ./temp3 && \
最后,删除(rm
)我们在整个过程中创建的每个临时文件。
rm temp1 temp2 temp3
【讨论】:
【参考方案6】:你可以使用这个工具:rnm
做你想做的事情的代码:
rnm /path/to/the/directory -fo -dp -1 -rs '/^\d+-//' -ss '^\d+-'
-fo
仅用于文件模式-dp
是目录深度(-1
表示无限深度)。-rs
是替换字符串。 \d+-
正则表达式被替换为空字符串。-ss
是搜索字符串,它搜索带有^\d+-
正则表达式的文件。 (不过可以省略,一些无害的错误信息会打印在屏幕上)。
【讨论】:
【参考方案7】:我真的很喜欢“重命名 *.mp3 *.mp4”。
但没有其他答案能告诉我这一点。所以我写了一个haskell程序来做。
https://hackage.haskell.org/package/batch-rename
有了这个,你可以做到: batch_rename "DCIM*.jpg" "*.png"
【讨论】:
【参考方案8】:还有一个方便的 GUI 工具pyRenamer
https://wiki.ubuntuusers.de/pyRenamer/
【讨论】:
【参考方案9】:vimv 允许您使用 Vim 的文本编辑功能重命名多个文件。
输入 vimv 会打开一个列出所有文件的 Vim 窗口,您可以进行模式匹配、视觉选择等来编辑名称。退出 Vim 后,文件将被重命名。
README 文件中的screencast 显示了它如何解决原始发帖人的问题。
[免责声明:我是该工具的作者]
【讨论】:
以上是关于批量重命名文件的主要内容,如果未能解决你的问题,请参考以下文章