新手求教:如何编写Bash脚本从文件名提取区号与门牌号?
提取文件名中的区号和门牌号(Bash脚本方案)
作为脚本新手,别担心——我们可以用Bash的正则表达式匹配来搞定这些格式不一的文件名。先梳理下你的文件名规律:所有文件都以ID-Final_RDX开头,后面跟着区号(可能是数字或字母组合)、门牌号(数字或带字母的编号),最后是日期后缀。下面是分步实现的方案,我会把每个部分讲明白:
1. 核心匹配逻辑
我们用Bash的=~操作符实现正则匹配,捕获区号和门牌号两个关键信息。针对你给出的所有格式,我写了一个兼容的正则模式:
pattern='ID-Final_RDX(?:[_-]|)([A-Za-z0-9]+)(?:[_-]|)([A-Za-z0-9]+)-[0-9]{2}_[0-9]{2}_[0-9]{4}'
拆解下这个模式的关键部分:
(?:[_-]|):匹配可选的分隔符(下划线、连字符,或者完全没有分隔符),?:表示这是个非捕获组,不会被保存为提取结果([A-Za-z0-9]+):第一个捕获组,匹配区号(支持数字、字母组合)([A-Za-z0-9]+):第二个捕获组,匹配门牌号(同样支持数字、字母组合)-([0-9]{2}_[0-9]{2}_[0-9]{4}):匹配最后的日期后缀,确保我们只提取前面的有效信息
2. 完整脚本示例
把下面的代码保存为extract_info.sh,然后给它加执行权限(chmod +x extract_info.sh):
#!/bin/bash # 定义匹配正则 pattern='ID-Final_RDX(?:[_-]|)([A-Za-z0-9]+)(?:[_-]|)([A-Za-z0-9]+)-[0-9]{2}_[0-9]{2}_[0-9]{4}' # 遍历传入的文件名(可以直接把文件名作为参数传入,或者写死在数组里) for filename in "$@"; do # 检查文件名是否匹配模式 if [[ "$filename" =~ $pattern ]]; then area_code="${BASH_REMATCH[1]}" house_num="${BASH_REMATCH[2]}" echo "文件名:$filename" echo "区号:$area_code" echo "门牌号:$house_num" echo "------------------------" else echo "⚠️ 文件名 $filename 不符合匹配规则,请检查格式" fi done
3. 测试脚本
你可以直接把所有目标文件名作为参数传给脚本,比如:
./extract_info.sh ID-Final_RDX_301_002-14_33_1992 ID-Final_RDX-311-004-14_28_1992 ID-Final_RDX311021-14_28_1992 ID-Final_RDX-XT-Se3-14_28_1992 ID-Final_RDX-XT-Se11-14_28_1992
执行后会输出:
文件名:ID-Final_RDX_301_002-14_33_1992 区号:301 门牌号:002 ------------------------ 文件名:ID-Final_RDX-311-004-14_28_1992 区号:311 门牌号:004 ------------------------ 文件名:ID-Final_RDX311021-14_28_1992 区号:311 门牌号:021 ------------------------ 文件名:ID-Final_RDX-XT-Se3-14_28_1992 区号:XT 门牌号:Se3 ------------------------ 文件名:ID-Final_RDX-XT-Se11-14_28_1992 区号:XT 门牌号:Se11 ------------------------
4. 扩展说明
如果以后遇到新的文件名格式,只需要调整正则表达式的pattern部分就行。比如如果出现新的分隔符,只要在(?:[_-]|)里加上对应的符号(比如(?:[_-]|#)就支持#作为分隔符)。
内容的提问来源于stack exchange,提问作者Jithin
相关产品推荐
相关产品推荐

