编写Shell脚本用正则匹配开头含多个商品编号的文件名
Shell正则匹配开头含多商品编号的文件名方案
最终可用正则表达式
针对你的需求,适用于Shell环境的正则如下:
^([0-9]{2,}_)+[a-zA-Z0-9_-]+\.(jpg|tif|zip|mp4|psd|eps|flv|mov|png|mp3|bnl|pdf)$
逐段解释规则
^:锁定文件名开头,确保从最起始位置开始匹配([0-9]{2,}_)+:匹配至少一个商品编号段,对应“多个商品编号”的要求[0-9]{2,}:匹配2位及以上的数字(商品编号主体)_:商品编号之间的分隔下划线+:允许前面的“数字+下划线”组合重复1次或多次(比如123456_、123456_654321_都符合)
[a-zA-Z0-9_-]+:匹配编号后的标签部分,支持字母、数字、下划线、连字符,至少1个字符\.:转义后的点字符(正则中.是通配符,必须转义才能匹配文件名的后缀分隔点)(jpg|tif|zip|mp4|psd|eps|flv|mov|png|mp3|bnl|pdf):精确匹配指定的扩展名列表$:锁定文件名结尾,避免匹配不符合扩展名的文件
你之前正则的问题分析
你写的([[:digit:]]{2,})+([_])+([[:alnum:]]{3,})+存在几个问题:
([_])+会匹配多个连续下划线,但你的需求是用单个下划线分隔编号- 没有限制扩展名,会匹配到任意后缀的文件
- 结构逻辑错误:强制要求每个数字段后必须跟多个下划线,无法匹配
123456_654321这种多编号连写的情况
捕获组的实用用法
捕获组就是用()把正则的某一部分包裹起来,核心作用有两个:
- 重复匹配:比如
([0-9]{2,}_)+里的分组,让“数字+下划线”这个单元可以重复多次,实现“多个商品编号”的匹配 - 提取内容:如果需要单独提取商品编号或标签,捕获组可以帮你精准截取对应部分。比如用
sed提取所有开头的商品编号:echo "123456_654321_test_tags.jpg" | sed -E 's/^(([0-9]{2,}_)+).*/\1/' # 输出结果:123456_654321_
Shell中实际使用示例
用grep筛选当前目录文件
ls | grep -E '^([0-9]{2,}_)+[a-zA-Z0-9_-]+\.(jpg|tif|zip|mp4|psd|eps|flv|mov|png|mp3|bnl|pdf)$'
用find遍历指定目录匹配文件
find /target/directory -type f -regex '^.*/([0-9]{2,}_)+[a-zA-Z0-9_-]+\.(jpg|tif|zip|mp4|psd|eps|flv|mov|png|mp3|bnl|pdf)$'
(find的正则需要匹配完整路径,所以开头加^.*/匹配路径前缀)
内容的提问来源于stack exchange,提问作者Scamus
相关产品推荐
相关产品推荐

