我正在编写一个perl脚本来解析标准输入中的制表符分隔数据。
该脚本删除前导空格和尾随空格,删除任何具有字符串“NULL”的字段,并将日期列重新格式化为“MMM DD YYYY HH:MM:SS:SSSAM”格式为“YYYYMMDD”格式。
示例输入:
93092 Apr 1 2010 12:00:00:000AM 59668370.60702875
22341 Apr 1 2010 12:00:00:000AM 51309196.84639429
27844 Apr 1 2010 12:00:00:000AM NULL
150465 Apr 22 2010 12:00:00:000AM 19706190.97586569
119364 Jul 20 2010 12:00:00:000AM 16335977.41009162
目标输出:
93092|20100401|59668370.60702875
22341|20100401|51309196.84639429
27844|20100401|
150465|20100422|19706190.97586569
119364|20100720|16335977.41009162
该脚本采用一个参数来表示具有需要转换的日期的列。在上面的示例中,我将调用“1”作为参数,因为第二列是需要转换的日期。多个列将以逗号分隔列表表示。
这是我迄今为止所做的。
#!/usr/bin/perl
my @date_cols = split(/,/, $ARGV[0]);
while (<STDIN>) {
my @fields = split(/\t/, $_, -1);
for (@fields) {
s/^\s+//;
s/\s+\z//;
s/^NULL\z//;
}
for (@fields[@date_cols]) {
##NEED HELP WITH DATE FORMATTING
}
print(join('|', @fields), "\n");
}
答案 0 :(得分:1)
使用Time::Piece很简单,很容易为您提供日期格式。 strptime
功能允许您定义要使用的模式; strftime
函数可以生成所需的输出格式。考虑:
use Time::Piece;
my $date = "Apr 1 2012 12:00:00AM";
my $t = Time::Piece->strptime($date,"%b %d %Y %H:%M:%S%p");
print $t->strftime("%Y%m%d\n");
这种方法的一个很好的特点是,一个或两个空格是否将月份和日期字段分开并不重要;结果是一样的。
答案 1 :(得分:0)
基于Dave Cross的上述建议,使用Time::Piece:
use Time::Piece;
while (<STDIN>) {
# Split each row into columns by white space
my @fields = split /\s+/;
# Rebuild the date ("Apr 1 2010") from columns 2 through 4
my $time_field = join ' ', @fields[1..3];
# Parse the date - see man strptime
my $date = Time::Piece->strptime($time_field, '%B %d %Y');
# Format the output - see man strftime
print join '|', $fields[0], $date->strftime('%Y%m%d'), $fields[5];
}
正则表达式是一个非常出色的工具,但日期很难看(甚至可怕)。只要有可能,我更喜欢使用已经存在的库来解析它们。