如何使用Unix的sed或awk拆分竖线分隔值并保留公共前缀?
刚好做过类似的需求,给你几个用awk和sed实现的方案,都是Unix环境下直接能用的单命令或简单组合,完美匹配你的需求~
方案1:用awk实现(最直观易读)
awk处理字段拆分天生擅长,思路非常直接:先按空格把每个产品条目分开,再提取每个条目的前缀(逗号前的部分),最后把竖线分隔的价格逐个和前缀拼接输出。
带注释的完整命令(方便理解逻辑)
awk '{ # 遍历当前行的每个产品条目(按空格分隔) for (i=1; i<=NF; i++) { # 把当前条目按逗号拆成前缀和价格串 split($i, arr, ",") prefix = arr[1] # 把价格串按竖线拆成单个价格的数组 split(arr[2], prices, "|") # 遍历每个价格,和前缀拼接后输出 for (j in prices) { print prefix "," prices[j] } } }' input.txt
紧凑单行版本(适合直接在终端执行)
awk '{for(i=1;i<=NF;i++){split($i,a,",");n=split(a[2],b,"|");for(j=1;j<=n;j++)print a[1]","b[j]}}' input.txt
方案2:用sed实现(纯文本流处理)
sed也能搞定这个需求,不过需要用循环来处理多个竖线的情况,核心是捕获前缀后,把每个竖线替换成「换行+前缀」,直到所有竖线都被处理完。
执行命令
-e 's/\([^,]*,\)\([^ |]*\)|\([^ |]*\)/\1\2\n\1\3/g' \ -e ':loop' \ -e 's/\([^,]*,\)\([^ |]*\)|\([^ |]*\)/\1\2\n\1\3/g' \ -e 't loop' \ input.txt
命令逻辑解释
- 第一个替换规则:捕获
逗号前的前缀+逗号,以及竖线前后的价格,把竖线替换成换行和前缀,完成第一次拆分 :loop定义循环标签,t loop表示如果上一次替换成功,就回到标签处重复执行,直到没有竖线可替换为止
测试效果验证
如果你的输入内容是:
PRODUCT1,PRICEa|PRICEb|PRICEc PRODUCT2,PRICEd PRODUCT3,PRICEe|PRICEf
运行任意一个命令后,输出都会是:
PRODUCT1,PRICEa PRODUCT1,PRICEb PRODUCT1,PRICEc PRODUCT2,PRICEd PRODUCT3,PRICEe PRODUCT3,PRICEf
内容的提问来源于stack exchange,提问作者Cozimetzer
相关产品推荐
相关产品推荐

