使用bash在文本行中指定数量的字符后分隔一行

时间:2015-10-15 21:32:25

标签: bash awk sed delimited-text

我有一个DataFile.txt,其中有多行像这样

010255500060010123066000952367006U00000000001721SMITH JOHN
536818991298231894872315612145497F00000000001721STUART FEDERIC

一行中的每个字符代表一个数字(位置),需要根据每行中的字符位置添加分隔符(空格)。例如:

  • 案例1:角色#2
  • 案例2:人物#10
  • 案例3:人物#26
  • 案例4:角色#44
  • 案例5:人物#48

......等等

然后输出这个规则和NewFile.txt:

01 02555000 6001012306600095 2367006U0000000000 1721 SMITH JOHN
53 68189912 9823189487231561 2145497F0000000000 1721 STUART FEDERIC

2 个答案:

答案 0 :(得分:4)

您可以在gnu-awk FIELDWIDTHS

中使用
awk 'BEGIN{FIELDWIDTHS = "2 8 16 18 4 100"; OFS=" "}
     {$1=$1; print}' DataFile.txt

你明白了,

01 02555000 6001012306600095 2367006U0000000000 1721 SMITH JOHN
53 68189912 9823189487231561 2145497F0000000000 1721 STUART FEDERIC

答案 1 :(得分:3)

我说:

sed -E 's/(.{2})(.{8})(.{16})(.{18})(.{4})/\1 \2 \3 \4 \5 /' filename

对于非常古老的GNU seds,您可能必须使用-r而不是-E(这是针对扩展的正则表达式语法。没有它,您需要大量的反斜杠,而不是#&# 39;完全有助于提高可读性。)

这只是捕捉字母组 - .{n}匹配n个任意字母 - 然后用添加的空格重新组合它们。

<强>附录:

如果使用的数字与问题中的数字相同很重要,请考虑Perl:

perl -pe 'for $i (48, 44, 26, 10, 2) { substr($_, $i, 0) = " "; }' filename

...因为替换零长度子串与插入相同。这些数字必须下降才能使用,这样已经插入的空间不会弄乱计数。

请注意,这可能会提供比sed方法更差的性能(因为必须计算更多的中间字符串),这可能是也可能不是问题,具体取决于文件大小。但是,如果性能不是考虑因素,并且您更喜欢使用绝对位置而不是字段宽度,则可以正常工作。