2009-07-21 1 views
2

Вход:Как я могу конкатенировать только некоторые поля с дефисом?

F1 F2   F3   F4  F5  F6 

4 ABCDEF1234 1111111111 20090101 00:00:00 XYZ 123 

Выход:

4 ABCDEF1234 1111111111 20090101-00:00:00 XYZ 123 

F представляет собой поле. F4 и F5 - это поля даты, которые необходимо объединить с дефисом. Есть ли быстрый скрипт Perl, который делает это?

ответ

3
printf("%-4s%s %s %s-%s %s\n", $F1, $F2, $F3, $F4, $F5, $F6); 

Этот ответ предполагает, что поля уже разделены на переменные $ F1 .. $ F6. Если данные представляют собой одну строку, то ответ регулярного выражения является более подходящим.

4
s/(\d{8})\s+(\d{2}:\d{2}:\d{2})/$1-$2/ 
+0

Интересно разночтение вопроса. Конечно, это также может быть F [0] .. $ F [5], который был предназначен, как и в режиме автосплит. –

+0

@chaos: Я собирался опубликовать то же самое. :-) –

1
$str = "4 ABCDEF1234 1111111111 20090101 00:00:00 XYZ 123"; 
@s = split /\s/,$str; 
$s[5] = join("-",$s[5],$s[6]); 
splice(@s,6,1); 
print join(" ",@s); 
3

Входной выглядит вид фиксированной ширины-у, который наводит на мысль pack и unpack.

my @F = unpack('A4 A11 A11 A19 A7', $input_line); 
$F[3] =~ s/\d\K\s+/-/; # Use lookaround (?<=\d) if \K is not available 
my $line = pack('A4 A11 A11 A19 A7', @F); 

Опять же, если это фиксируется достаточно, вы можете просто пойти:

substr($input_line, 34, 1, '-'); 
0

Непосредственно в командной строке:

$ perl -n -e '@fields = split; printf "%s %s %s %s-%s %s %s\n", $fields[0], $fields[1], $fields[2], $fields[3], $fields[4], $fields[5]' input.txt > output.txt 

Помните, что это эквивалентно положить:

#!/usr/bin/perl -w 
while (<>) { 
    @fields = split; 
    printf "%s %s %s %s-%s %s %s\n", $fields[0], $fields[1], $fields[2], $fields[3], $fields[4], $fields[5]; 
} 
1

Если формат имеет фиксированную связь ширина lumn:

perl -pe'substr$_,34,1,"-"' 

В противном случае что-то вроде:

perl -ane'printf"%-4s%s %s %s-%s %s\n",@F' 
+0

+1 (я знал, что был более короткий путь!) –