Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 在大型CSV文件中搜索/替换和移动列?_Perl_Shell_Unix_Scripting_Sed - Fatal编程技术网

Perl 在大型CSV文件中搜索/替换和移动列?

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

我有一些非常大的文件(大于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.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