我正在尝试将一大堆数据转换为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做到这一点。这是一种方法:
perl -pe 's/(.{12})(.{5})(.{5})(.{12})/$1,$2,$3,$4,/' < input-file > output-file
替换中的匹配模式从每行的开头捕获四组文本,其中包含 12、5、5 和 12 个任意字符。替换模式在每个组后放置一个逗号。
使用 GNU awk,你可以写
gawk 'BEGIN {FIELDWIDTHS="12 5 5 12"; OFS=","} {$1=$1; print}'
$1=$1
部分是强制awk重写类似内容,合并输出字段分隔符,而不更改任何内容。
这在很大程度上是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