Perl 在大型CSV文件中搜索/替换和移动列?
我有一些非常大的文件(大于2GB),文件中的文本格式如下:Perl 在大型CSV文件中搜索/替换和移动列?,perl,shell,unix,scripting,sed,Perl,Shell,Unix,Scripting,Sed,我有一些非常大的文件(大于2GB),文件中的文本格式如下: TimeStamp,BidPrice,BidVolume,AskPrice,AskVolume 2013/4/18;22:5:42.668;13266;10;13279;10 2013/4/18;22:10:48.820;13271;10;13279;10 2013/4/18;22:12:0.956;13266;10;13279;10 ... 我想完成以下任务 将时间戳中的第一个分号“;”替换为空格 使时间戳的格式如下:yyyy.M
TimeStamp,BidPrice,BidVolume,AskPrice,AskVolume
2013/4/18;22:5:42.668;13266;10;13279;10
2013/4/18;22:10:48.820;13271;10;13279;10
2013/4/18;22:12:0.956;13266;10;13279;10
...
我想完成以下任务
- 将时间戳中的第一个分号“;”替换为空格
- 使时间戳的格式如下:yyyy.MM.dd HH:MM:ss
- 替换其余分号“;”至逗号“,”
- 切换BidVolume和AskPrice列索引
TimeStamp,BidPrice,AskPrice,BidVolume,AskVolume
2013.04.18 22:04:55,13256,13279,10,10
2013.04.18 22:05:42,13266,13279,10,10
2013.04.18 22:10:48,13271,13279,10,10
...
谁能告诉我怎么做?我将不胜感激。这里有一个快速而肮脏的方法:
sed 's/;/ /; s/;/,/g; s/\//./g;' inputfile > outputfile
awk '
BEGIN { FS = OFS = "," }
NR==1 {
print $1, $2, $4, $3, $5; next
}
{
split($0,fld,/;/); split(fld[1],d,/\//)
for(j=2;j<=3;j++) {
d[j] = (length(d[j]) == 1) ? "0"d[j] : d[j]
}
sub(/\..*/,"",fld[2]); split(fld[2],t,/:/)
for(i=1;i<=3;i++) {
t[i] = (length(t[i]) == 1) ? "0"t[i] : t[i]
}
printf "%s.%s.%s %s:%s:%s,", d[1], d[2], d[3], t[1], t[2], t[3];
print fld[3], fld[5], fld[4], fld[6]
}' file
或许以下内容会有所帮助:
perl -naF"/[\/;:.]/" -pe '$_ = $. == 1 ? $_ : sprintf "%d.%02d.%02d %02d.%02d.%02d,%d,%d,%d,%d\n", @F[0..5,7..10]' inFile > outFile
数据集上的输出:
TimeStamp,BidPrice,BidVolume,AskPrice,AskVolume
2013.04.18 22.05.42,13266,10,13279,10
2013.04.18 22.10.48,13271,10,13279,10
2013.04.18 22.12.00,13266,10,13279,10
这个简短的Perl程序可以满足您的要求。它希望输入文件的路径作为命令行上的参数,并将修改后的数据打印到
STDOUT
use strict;
use warnings;
while (<>) {
chomp;
s{^(\d+)/(\d+)/(\d+);(\d+):(\d+):(\d+)[^;]*}{
sprintf '%04d.%02d.%02d %02d.%02d.%02d', $1, $2, $3, $4, $5, $6;
}e;
tr/;/,/;
my @fields = split /,/;
print join(',', @fields[0,1,3,2,4]), "\n";
}
您的示例显示MM=.
4
。。。如果您重新指定为MM=。04
,那么从长远来看,您会更快乐。祝你好运。忘了出价然后问。有人可能会要求消费者注意这一点。谢谢,我们可以将时间戳格式化为yyyy.MM.dd HH:MM:ssThank,这可以工作,但日期缺少0,我如何修复它?2013.04.18@user1565287您没有在output.opps.中指定这一点。。我的错。我编辑了我的第一篇文章,你能让脚本也添加0到最新版本吗,thanks@user1565287没问题。更新了解决方案
use strict;
use warnings;
while (<>) {
chomp;
s{^(\d+)/(\d+)/(\d+);(\d+):(\d+):(\d+)[^;]*}{
sprintf '%04d.%02d.%02d %02d.%02d.%02d', $1, $2, $3, $4, $5, $6;
}e;
tr/;/,/;
my @fields = split /,/;
print join(',', @fields[0,1,3,2,4]), "\n";
}
TimeStamp,BidPrice,AskPrice,BidVolume,AskVolume
2013.04.18 22.05.42,13266,13279,10,10
2013.04.18 22.10.48,13271,13279,10,10
2013.04.18 22.12.00,13266,13279,10,10