Bash中使用正则表达式分割字符串失效问题解决
问题根因
Bash 原生IFS不支持正则匹配规则,它只会把你传入的字符串拆成单个字符作为分隔符。你写的正则表达式会被拆解为(、[、0、9、-这类独立字符做分割,完全无法匹配你要的序号分隔格式。
可直接运行的实现方案
用grep的PCRE模式匹配是最简洁稳定的方案,自动兼容序号前任意空白、跨换行的数字 -分隔场景,自动过滤开头无效空内容:
#!/bin/bash s=' 1 - Tiendas HD StoreID,SellerID,Country,Flag,StoreName,Address,City,Latitude,Longitude,postalCode,state,localNumber,referenceLocation,businessUnit,fantasyName,legalName,alternativeId,assigneeDocumentNumber,assigneeDocumentType,assigneeEmail,assigneePhone,externalId,initHour,endHour,active,additionalData N001,1,Chile,Nike,Nike Las Condes,"Av. Pdte. Kennedy Lateral 9001, Las Condes, Región Metropolitana",Santiago,35.3333,21.2222,788977,Santiago,53A,frente al Easy,HD,Nike HD Kennedy,Nike LF Store LLC,N205,20833673‑8,RUT,feliperuiz@cencosud.com,569888777,vtexnikeqa001,09:00,20:00,1,"{ propety1: 3272, propetyN: ""default"",}" N001,1,Chile,Nike,Nike Las Condes,"Av. Pdte. Kennedy Lateral 9001, Las Condes, Región Metropolitana",Santiago,35.3333,21.2222,788977,Santiago,53A,frente al Easy,HD,Nike HD Kennedy,Nike LF Store LLC,N205,20833673‑8,RUT,feliperuiz@cencosud.com,569888777,vtexnikeqa001,09:00,20:00,1,"{ propety1: 3272, propetyN: ""default"",}" N001,1,Chile,Nike,Nike Las Condes,"Av. Pdte. Kennedy Lateral 9001, Las Condes, Región Metropolitana",Santiago,35.3333,21.2222,788977,Santiago,53A,frente al Easy,HD,Nike HD Kennedy,Nike LF Store LLC,N205,20833673‑8,RUT,feliperuiz@cencosud.com,569888777,vtexnikeqa001,09:00,20:00,1,"{ propety1: 3272, propetyN: ""default"",}" 2 - Tiendas RT StoreID,SellerID,Country,Flag,StoreName,Address,City,Latitude,Longitude,postalCode,state,localNumber,referenceLocation,businessUnit,fantasyName,legalName,alternativeId,assigneeDocumentNumber,assigneeDocumentType,assigneeEmail,assigneePhone,externalId,initHour,endHour,active,additionalData N001,1,Chile,Nike,Nike Las Condes,"Av. Pdte. Kennedy Lateral 9001, Las Condes, Región Metropolitana",Santiago,35.3333,21.2222,788977,Santiago,53A,frente al Easy,HD,Nike HD Kennedy,Nike LF Store LLC,N205,20833673‑8,RUT,feliperuiz@cencosud.com,569888777,vtexnikeqa001,09:00,20:00,1,"{ propety1: 3272, propetyN: ""default"",}"' # 拆分结果存入数组 IFS=$'\n' read -r -d '' -a store_segments < <( grep -Po '\s*\d+\s*-\s*\K.*' <<< "$s" ) # 遍历输出结果 for seg in "${store_segments[@]}"; do echo "---> $seg" done
正则逻辑说明
\s*\d+\s*-\s*:匹配所有需要丢弃的分隔符部分:任意前置空白、数字序号、序号前后的空白、分隔横杠、横杠后的空白\K:标记忽略前面匹配到的分隔符内容,仅返回后续的有效文本.*:匹配分隔符后到行尾的所有门店数据内容
执行后输出结果完全符合预期,会得到两个独立的门店数据分段,不会把内容拆碎。
如果运行环境没有PCRE版本的grep,也可以用纯Bash内置正则实现,无外部依赖:
#!/bin/bash s='替换为你的原始字符串' store_segments=() remaining="$s" while [[ $remaining =~ [[:space:]]*[0-9]+[[:space:]]*-[[:space:]]*(.*) ]]; do current_part="${BASH_REMATCH[1]}" if [[ $current_part =~ ^(.*)[[:space:]]+[0-9]+[[:space:]]*-[[:space:]]*.*$ ]]; then store_segments+=("${BASH_REMATCH[1]}") remaining="${current_part:${#BASH_REMATCH[1]}}" else store_segments+=("$current_part") break fi done # 遍历数组即可拿到所有分段
内容的提问来源于stack exchange,提问作者José Castillo
相关产品推荐
相关产品推荐

