如何用 shell 脚本优雅的遍历文件夹内所有文件名的中文字符并替换?

2022-09-04 23:04:15 +08:00
 RayGZJ
因为在收集学生的报名考试资料,但有些班主任不是完全按照我发的格式命名文件照片,目前我已将所有证件照都移动至一个文件夹内,我需要身份证号命名照片
如:
32000000000000123.jpg
…..

而实际文件名是这样的
文件内容
张三 32000000000000123.jpg

32000000000000123 李四.jpg

用了正则脚本\u4E00-\u9FA5 还是不行 是我打开方式问题吗?
3591 次点击
所在节点    Linux
44 条回复
RayGZJ
2022-09-04 23:06:47 +08:00
有 rename 的 CLI 工具 但是 man rename 是在太干 也考虑 python 实现或许更简单些?
yfugibr
2022-09-04 23:08:06 +08:00
```
rename -v 's/.*(\d+).*\.(.*?)/$1.$2/' * -n
```
确定没问题就去掉 -n 参数
yfugibr
2022-09-04 23:10:06 +08:00
@yfugibr #2 纠正一下
```
rename -v 's/.*?(\d+).*?\.(.*?)/$1.$2/' * -n
```
RayGZJ
2022-09-04 23:13:53 +08:00
@yfugibr 感谢回复

实际操作后会删除身份证号最后一位字母位 X
RayGZJ
2022-09-04 23:14:41 +08:00
@RayGZJ
@RayGZJ
@yfugibr
不带 X 的删除正常
Jirajine
2022-09-04 23:14:51 +08:00
用 elvish ,比 bash 顺手,也比 Python 方便:
put **.jpg | peach {|name|
use re
var number = (re:replace '[^0-9]' '' $name)
mv $name $number.jpg
}
peach 并发执行,换成 each 顺序执行。
Jirajine
2022-09-04 23:17:08 +08:00
带 X 换成 '[^0-9X]'
RayGZJ
2022-09-04 23:20:23 +08:00
@Jirajine 感谢老师回复
哈哈哈为了好看用的 ozm
yfugibr
2022-09-04 23:22:14 +08:00
@RayGZJ #5 忘了还有这个
```
rename -v 's/.*(\d{17}[\dxX]).*\.(.*?)/$1.$2/' * -n
```
这个应该没问题了
RayGZJ
2022-09-04 23:25:10 +08:00
@yfugibr 谢谢你老师
问题解决啦,我要好好学习正则

s/.*(\d{17}[\dxX]).*\.(.*?)/$1.$2/

这一块是功能实现的正则吗
yfugibr
2022-09-04 23:29:37 +08:00
@RayGZJ #10 对,正则主要是里面的
```
.*(\d{17}[\dxX]).*\.(.*?)
```
可以找语法看看,还是比较简单的
wxf666
2022-09-04 23:33:06 +08:00
这样?

rename -n -v 's/^\s*.*?\s*(\d+[\dxX])\s*.*?(\.[^.]+)$/$1$2/' *

一样,确定没问题就去掉 -n 参数
wxf666
2022-09-04 23:35:43 +08:00
也对,名字里没有 0-9 x X ,直接 's/^.*?(\d+[\dxX]).*?(\.[^.]+)$/$1$2/' 就好
wxf666
2022-09-04 23:39:18 +08:00
@Jirajine 这个为啥又比 bash 顺手了?

上次有人说 powershell (在交互式下)比 bash 强大,是因为参数显式,严谨安全。。
Jirajine
2022-09-04 23:54:41 +08:00
@wxf666 语法现代、没有 shell 那么多乱七八糟 word splitting 之类的糟粕,支持 namespace 。
支持 list/map 结构化数据类型,同时完美兼容传统的*nix 命令行工具和 byte pipe 。
顺不顺手,你直接看我上面写的,还有官网 elv.sh 上的示例,可读性比长串正则+特殊语法好的多,同时也不像 pwsh 那么冗长命名。
pwsh 就是个 dotnet script ,当 shell 实在是无比糟糕,命名冗长、过度 OOP ,外部命令是二等公民,管道完全不能用,只让你用 cmdlet 。
wxf666
2022-09-05 00:00:46 +08:00
@Jirajine 我感觉你那个示例。。我更愿意写一行 rename + 正则。。
wxf666
2022-09-05 00:15:01 +08:00
@Jirajine 另外,你那个示例的逻辑,可以写成:rename 's/[^\dxX]//g; s/$/.jpg/' *


我觉得,交互式下的 shell ,简短快捷,还是很重要的吧

word splitting 、特殊语法 也是为这个目的服务的

不搞这些,就不可避免地会写长


简短 和 美观,感觉不可兼得,就看个人喜好了

反正交互式下,我是愿意阅读 bash 规则,牺牲一定可读性,来换取输入时的便捷的


就好比有人会放弃易读的拼音,练习五笔,去换取快捷打字一样(我折中一下,学了个双拼。。)
aloxaf
2022-09-05 00:57:11 +08:00
来用 zsh

autoload -Uz zmv
zmv -n '*.jpg' '${f//[^0-9X]/}.jpg'
haoliang
2022-09-05 01:44:44 +08:00
正巧我打算换个 shell ,看到楼上对 elvish 、bash 、zsh 的示例,我决定试试 elvish ,哈哈。
虽然我的 login shell 是 zsh ,但我从来都只写 bash 脚本,复杂的就换 python 了。可以说 zsh 是我最熟悉的陌生人,它的大部分功能我都没用过。elvish 用 go 实现,方便阅读实现、定制,相见恨晚啊!
Jirajine
2022-09-05 02:37:33 +08:00
@wxf666 你上面的那种长正则,可读性很差的,不常写正则的人不用 regex101.com 这样的工具都看不懂。
rename 自己又发明了一种 dsl 语言,不熟悉的人用起来有额外的心智负担。而且你还得同时处理 shell/rename 自己的语言 /regex 的转义,再配上 glob 。

word splitting 可不是简短,是历史包袱,导致所有变量引用都得用引号括起来。
特殊语法如 man zshexpn 看一看,正常编程语言简单的字符串处理有多麻烦。

elvish 也是为交互式设计的,完全符合简短快捷易输入,PowerShell 才是故意搞得冗长、难以输入并美其名曰“可读性”的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/877692

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX