如何在Unix中使用sed提取指定位置数据并处理后追加到行尾
使用sed实现指定位置内容提取、格式化并追加到行尾
我来给你一个能完美满足需求的sed方案,还会一步步拆解每个环节的作用,方便你根据自己的实际场景调整:
完整命令(针对你的示例)
echo "123456 890 2345" | sed -E ' # 1. 提取第7-11位内容,同时把原位置替换为等长空格,保存原行到暂存区 s/^(.{6})(.{5})(.*)/\1 \3/;h;s/^.{6}(.{5}).*/\1/ # 2. 去除提取内容的两端空格 :s;s/^[[:space:]]+//;t s;s/[[:space:]]+$// # 3. 补前导0,直到长度达到15位 :a;s/^.{,14}$/0&/;t a # 4. 把格式化后的内容追加到原行末尾 G;s/(.*)\n(.*)/\2\1/ '
执行结果
运行后会输出:
123456 23450000000000890
和你给出的示例效果一致(示例里的0数量可能是笔误,这里补到15位是12个0+3位的890,总长度刚好15)
各步骤详解
提取指定位置并保留原行结构
s/^(.{6})(.{5})(.*)/\1 \3/:把行拆成三部分:前6个字符(对应第1-6位)、中间5个字符(第7-11位)、剩余内容。把中间部分替换为5个空格(保证原行结构不变),然后用h把修改后的行存到暂存区。s/^.{6}(.{5}).*/\1/:单独提取出中间的5个字符,此时sed的工作区里是890。
去除两端空格
:s;s/^[[:space:]]+//;t s:循环删除开头的所有空格,直到没有开头空格为止。s/[[:space:]]+$//:一次性删除结尾的所有空格,得到干净的890。
补前导0到15位
:a;s/^.{,14}$/0&/;t a:循环在字符串开头加0,只要当前长度≤14就继续加,直到长度刚好15位。
追加到原行末尾
G:把暂存区里的原行(123456 2345)追加到工作区,此时工作区内容是000000000000890\n123456 2345。s/(.*)\n(.*)/\2\1/:把两行内容交换位置,得到最终的拼接结果。
调整提取位置的方法
如果要提取其他位置,只需要修改正则里的数字:
- 比如要提取第
X到Y位,那么前部分的长度是X-1(即{X-1}),中间部分的长度是Y-X+1(即{Y-X+1}),同时替换的空格数量也要和中间部分长度一致。
内容的提问来源于stack exchange,提问作者Kumar Parera
相关产品推荐
相关产品推荐

