我有一个包含3个字段的输入文件,如图所示。我想根据应用程序对服务器进行分组。我对任何这些字符(花括号,空格,点)的应用程序都不感兴趣。日期应转换为dd-mmm-yyyy(2013年5月18日)格式。
在帮助下,我已经部分实现了我想要的输出形式但是在格式化日期方面失败了。
我非常感谢格式化日期方面的任何帮助,也感谢我从输出中删除了应用程序中包含特殊字符的记录。
输入:
Date Server application
01/02/2013 00:00 abc123 perl_module_1
01/02/2013 00:00 abc123 oracle_patch_201
03/05/2014 00:00 abc123 Microsoft()_pa.1.tch_71 (2)
04/04/2015 00:00 xyz1 oracle_patch_201
02/12/2015 00:00 xyz1 Cygwin_app
03/11/2013 00:00 lpr567 perl_module_1
输出:
ABL "TEST:perl_module_1" /UPDATE=(server[("abc123","lpr567"),("01-FEB-2013 00:00","03-NOV-2013 00:00")])
ABL "TEST:oracle_patch_201" /UPDATE=(server[("abc123","xyz1"),("03-MAY-2014 00:00","04-APR-2015 00:00")])
ABL "TEST:Cygwin_app" /UPDATE=(server[("xyz1"),("02-DEC-2015 00:00")])
这是我到目前为止所尝试的内容。
#!usr/bin/perl
use strict;
use warnings;
my $file = 'input.txt';
open my $info, $file or die "could not open $file: $!";
open(my $fh, '>', 'output.cmd');
my $application_string;
my $date_string;
my $oracledate;
my %applications_on;
my %servers_on;
my %date_on;
while ( <$info> ) {
chomp;
my ( $date, $time, $server, $application ) = split;
my %month_name;
@month_name{ 0 .. 11 } = qw(Jan Feb Mar Apr May Jun Jul Aug Sept Oct Nov Dec);
my ( $day, $month, $year ) = split ('/', $date);
$date = join " ", $day, $month_name{$month}, $year;
# my @date_values = split ('/',$date);
# my $date_values[1] =~ s/01/JAN/;
# $date = ($date_values[0].'-'.$date_values[1].'-'.$date_values[2]);
push ( @{ $servers_on{$application} }, '"'.$server.'"');
push ( @{ $date_on{$application} }, '"'.$date.'"');
}
foreach my $application ( keys %servers_on, keys %date_on ) {
my $server_string = join ( ",", @{ $servers_on{$application} } ) ;
my $date_string = join ( ",", @{ $date_on{$application} } );
printf $fh "ABL \"TEST:$application\" /UPDATE=(server[($server_string),($date_string)])\n";
}
close $info;
答案 0 :(得分:0)
使用特殊字符删除记录:
这实际上取决于您对&#34;特殊字符的定义。&#34;
while ( <$info> ) {
chomp;
next if /[ whatever characters you think are special ]/;
或者可能更好:
next unless /^[ -~]+$/;
除非它只包含低ascii可打印字符,否则应跳过该行。
转换日期:
use Time::Piece
...
my $new_date = uc Time::Piece
->strptime($date, '%m/%d/%Y')
->strftime('%d-%b-%Y');
答案 1 :(得分:0)
让我们从日期开始。使用Time::Piece可帮助您翻译和格式化日期。使用标准的Perl模块将使您的工作更轻松。
您的文件是如何设置的?这些标签是分开的字段吗?如果是这样,您应该使用Text::ParseWords来帮助您解析文本文件。由于我不知道实际的格式,我会作弊。
这将向您展示如何使用Time::Piece
来读取和格式化日期。它还向您展示了如何使用Perl正则表达式抛出第一行和任何带有特殊字符的应用程序。 /\W/
表示不是字母,数字或下划线的任何字符。
我将你的线分成一个或多个空格的四个数据。 Time::Piece->strptime
需要时间和格式并返回可用于进一步处理的日期对象。该格式使用%x
个字符来表示各种日期和时间。 date的联机帮助页通常包含%x
格式及其代表的内容。获得约会后,我会使用sprintf格式化日期。
我将所有这些放入哈希值,然后将 引用 推送到包含您感兴趣的所有数据的数组中。注意反斜杠%data
语句中push
的前面。这非常重要,或者我只是将六个字段推入我的`@lines。如果您之前没有使用过Perl引用,则应阅读tutorial。引用允许您创建复杂的数据结构。
#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
use Data::Dumper;
use Time::Piece;
my @lines;
while ( my $line = <DATA> ) {
chomp $line;
next if $line !~ /^\d/; # Skip first line
my ( $date, $time, $server, $application ) = split /\s+/, $line;
next if $application =~ /\W+/;
my $time_format = "%m/%d/%Y %H:%M";
my $date_obj = Time::Piece->strptime( "$date $time", $time_format)
or die qq(Invalid datetime format "$date $time".);
my $formatted_date = sprintf "%02d-%s-%04d %02d:%02d",
$date_obj->mday, $date_obj->month, $date_obj->year,
$date_obj->hour, $date_obj->min;
my %data = (
date => $formatted_date,
app => $application,
server => $server,
);
push @lines, \%data;
}
say Dumper \@lines;
__DATA__
Date Server application
01/02/2013 00:00 abc123 perl_module_1
01/02/2013 00:00 abc123 oracle_patch_201
03/05/2014 00:00 abc123 Microsoft()_pa.1.tch_71 (2)
04/04/2015 00:00 xyz1 oracle_patch_201
02/12/2015 00:00 xyz1 Cygwin_app
03/11/2013 00:00 lpr567 perl_module_1
这将打印出来:
$VAR1 = [
{
'server' => 'abc123',
'time' => '02-Jan-2013 00:00',
'app' => 'perl_module_1'
},
{
'app' => 'oracle_patch_201',
'server' => 'abc123',
'time' => '02-Jan-2013 00:00'
},
{
'app' => 'oracle_patch_201',
'server' => 'xyz1',
'time' => '04-Apr-2015 00:00'
},
{
'app' => 'Cygwin_app',
'server' => 'xyz1',
'time' => '12-Feb-2015 00:00'
},
{
'server' => 'lpr567',
'time' => '11-Mar-2013 00:00',
'app' => 'perl_module_1'
}
];
从这里开始,你应该能够弄清楚如何获得你想要的输出。