【问题标题】:Insert comma after certain byte range在特定字节范围后插入逗号
【发布时间】:2012-11-23 15:28:16
【问题描述】:

我正在尝试将大量数据转换为 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 等字符后添加一个逗号。

感谢您的帮助,谢谢!

【问题讨论】:

  • 请向我们展示输入和预期输出的示例。

标签: perl bash csv awk


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    使用 GNU awk,您可以编写

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

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

    【讨论】:

      【解决方案3】:

      这对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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-07
        • 2010-10-17
        • 1970-01-01
        • 2023-03-11
        相关资源
        最近更新 更多