在某个字节范围后插入逗号

时间:2012-12-05 17:55:12

标签: perl bash csv awk

我试图将大量数据转换为CSV格式。它基本上是一个没有空格的巨型列表,行由换行符分隔。我已经创建了一个bash脚本,它基本上循环遍历文档,清除行,削减字节范围,然后添加逗号并将其附加到行尾。它看起来像这样:

awk -v n=$x 'NR==n { print;exit}' PROP.txt | cut -c 1-12      | tr -d '\n' >> $x.tmp
awk -v n=$x 'NR==n { print;exit}' PROP.txt | cut -c 13-17     | tr -d '\n' | xargs -I {} sed -i '' -e 's~$~,{}~' $x.tmp
awk -v n=$x 'NR==n { print;exit}' PROP.txt | cut -c 18-22     | tr -d '\n' | xargs -I {} sed -i '' -e 's~$~,{}~' $x.tmp
awk -v n=$x 'NR==n { print;exit}' PROP.txt | cut -c 23-34     | tr -d '\n' | xargs -I {} sed -i '' -e 's~$~,{}~' $x.tmp

问题是这个速度非常慢,而且数据大约有400k行。我知道必须有更好的方法来实现这一目标。基本上我只需要在每行12/17/22/34等字符之后添加一个逗号。

感谢任何帮助,谢谢!

3 个答案:

答案 0 :(得分:2)

使用Perl有很多方法可以做到这一点。这是一种方式:

perl -pe 's/(.{12})(.{5})(.{5})(.{12})/$1,$2,$3,$4,/' < input-file > output-file

替换中的匹配模式从每行的开头捕获四组文本,包含12,5,5和12个任意字符。替换模式在每个组之后放置一个逗号。

答案 1 :(得分:1)

使用GNU awk,你可以写

gawk 'BEGIN {FIELDWIDTHS="12 5 5 12"; OFS=","} {$1=$1; print}'

$1=$1部分是强制awk重写之类,合并输出字段分隔符,而不改变任何内容。

答案 2 :(得分:1)

这对substr非常重要。

use strict;
use warnings;

my @widths = (12, 5, 5, 12);
my $offset;

while (my $line = <DATA>) {
  for my $width (@widths) {
    $offset += $width;
    substr $line, $offset, 0, ',';
    ++$offset;
  }
  print $line;
}

__DATA__
1234567890123456789012345678901234567890

<强>输出

123456789012,34567,89012,345678901234,567890