2017-02-17 21 views
1

У меня есть вход этого формата:Regexp для удаления определенных столбцов

<apple1> <orange1> : <apple2> <orange2> : <apple3> <orange3> : ... 

Этот вход является неопределенной длины и состоит из яблонь-оранжевый пар с различными оранжевыми и яблоневых частей, разделенных двоеточием.

Я хотел бы, чтобы это как выход:

<apple1> <orange1> : <orange2> : <orange3> : ... 

I. е. все части яблока, но первые удалены.

Каждая часть яблока имеет ширину 14 символов, каждая оранжевая часть - 19 символов.

Я пытался что-то вроде этого:

sed -r 's/.{14}(.{19}):/\1:/g' 

Но это всегда столкнулись с проблемами, пропустив первую часть яблока.

Может ли кто-нибудь предоставить регулярное выражение, решая эту задачу?

Реальный пример ввода:

appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo 
foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb 
xxxxxxxxxxxxxxooooooooooooooooooo:ppppppppppppppqqqqqqqqqqqqqqqqqqq:nnnnnnnnnnnnnnttttttttttttttttttt 

Вывод должен быть таким:

appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo 
foofoofoofoofobarbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb 
xxxxxxxxxxxxxxooooooooooooooooooo:qqqqqqqqqqqqqqqqqqq:ttttttttttttttttttt 
+0

где «символ трубы»? – Kent

+1

Извините, редактирование получилось диким. Я имел в виду толстую кишку. Вопрос редактируется. – Alfe

+0

Как вы храните выход? Это имеет значение, потому что вы можете сделать что-то вроде 'head -c 14', чтобы получить первое яблоко в выходной файл. –

ответ

1

Ваше регулярное выражение для sed было почти правильным. Просто повторяйте «: _14_19» снова и снова и удалите 14 частей. (Примечание: Я использую запятые в качестве разделителей регулярных выражений ниже, потому что они легче читать.)

$ export A='appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb:xxxxxxxxxxxxxxooooooooooooooooooo:ppppppppppppppqqqqqqqqqqqqqqqqqqq:nnnnnnnnnnnnnnttttttttttttttttttt' 
$ echo $A | sed -Ee 's,:.{14}(.{19}),:\1,g' 
appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo:barbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb:ooooooooooooooooooo:qqqqqqqqqqqqqqqqqqq:ttttttttttttttttttt 
+0

Да, я думаю, что это будет сделано, если ничего лучше не всплывет. Я надеялся не полагаться на то, что в некоторых строках есть двоеточие, но поскольку они являются частью моей спецификации, я думаю, что это кратчайшее решение. – Alfe

1

Эта работа является более подходящим для awk в качестве входного файла хорошо структурирован по строкам и столбцам с использованием известного разделителей ИЭ colon:

awk 'BEGIN{FS=OFS=":"} {for (i=2; i<=NF; i++) $i = substr($i, 15)} 1' file 

appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo 
foofoofoofoofobarbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb 
xxxxxxxxxxxxxxooooooooooooooooooo:qqqqqqqqqqqqqqqqqqq:ttttttttttttttttttt 

Этот awk com mand использует : в качестве входного + разделителя вывода и начиная с 2-го поля в каждой записи, он устанавливает каждое поле в подстроку того же поля от 15th.

0

С Perl ..

Наш Входной: appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo

позволяет предположить a=appleappleappl (14 символы) b=orangeorangeorangeo (19 символов) c=appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo (остальная часть линии, которая является повторяющейся комбинацией a и b.

Ожидаемый результат: Перед кулаком толстой кишки (:), как a и b сохраняются и после первого двоеточия, только b сохраняются. $ {a} $ {b}: $ {b}: $ {b}: .... (пожалуйста, поправьте меня, если я ошибаюсь)

Итак, вот еще раз, вход и выход.

Наш вход:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo

Ожидаемый результат:appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo

Пожалуйста, попробуйте этот скрипт: (Как уже упоминалось выше, это с помощью Perl и не оболочки).

%[email protected]> cat apple.pl 
#!/usr/bin/perl 

use strict; 
use warnings; 

while (<>) { 
    chomp $_ ; 
    my @tmp = split /:/, $_ ; 
    my ($a,$b) = (substr($tmp[0],0,14), substr($tmp[0],14,19)) ; 
    my $str = "$a"."$b" ; 

    foreach my $i (1..$#tmp) { 
    $tmp[$i] =~ s/$a//g ; 
    $str .= ":"."$tmp[$i]" ; 
    } 
    print "$str\n" ; 
} 
%[email protected]> 

Выход сценария:

%[email protected]> cat td_apple |./apple.pl 
appleappleapplorangeorangeorangeo:orangeorangeorangeo:orangeorangeorangeo 
foofoofoofoofobarbarbarbarbarbarb:barbarbarbarbarbarb:barbarbarbarbarbarb 
xxxxxxxxxxxxxxooooooooooooooooooo:ppppppppppppppqqqqqqqqqqqqqqqqqqq:nnnnnnnnnnnnnnttttttttttttttttttt 

Образец данных:

%[email protected]> cat td_apple 
appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo:appleappleapplorangeorangeorangeo 
foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb:foofoofoofoofobarbarbarbarbarbarb 
xxxxxxxxxxxxxxooooooooooooooooooo:ppppppppppppppqqqqqqqqqqqqqqqqqqq:nnnnnnnnnnnnnnttttttttttttttttttt 
%[email protected]> 

Спасибо.

+0

Ничего себе. Это много. Спасибо, но вся идея использования регулярного выражения заключалась в том, чтобы держать его маленьким и простым. Извините, но ваше решение выходит из строя в этом аспекте. – Alfe

+0

Вы правы! Не могу не согласиться. Да, это решение не мало; – User9102d82

+0

@Alfe: Могу ли я спросить вас, сколько данных этого типа вам нужно обработать? каков ваш сценарий, можно поделиться некоторой информацией. – User9102d82