2009-11-20 11 views
1

У меня есть текстовые файлы, созданные одним из моих инструментов со структурой, показанной ниже.Обработка и удаление текста

1 line text 
(space) 
multiple 
lines 
text 
(space) 
multiple 
lines 
text 
nr 2 
---------------------------------------------------------- (58 '-' characters) 
different 1 line text 
(space) 
different 
multiple 
lines 
text 
(space) 
different 
multiple 
lines 
text 
nr 2 
---------------------------------------------------------- 
different 1 line text 
(space) 
different 
multiple 
lines 
text 
(space) 
different 
multiple 
lines 
text 
nr 2 
---------------------------------------------------------- 
(space) 

Каждый файл начинается с 1 строкового текста и заканчивается разделителем знаков «-» и пространством. В каждом файле разное количество разделов, и каждый раздел, «посередине», начинается и заканчивается знаками «-». Ниже я хотел бы достичь.

multiple 
lines 
text 
(space) 
different 
multiple 
lines 
text 
(space) 
different 
multiple 
lines 
text 

Я хотел бы, чтобы удалить все лайнеры, все 58 «-» символы разделителей и все «второй» несколько вкладышей и имеют только «первые» несколько гильз от каждой секции один под другим разделены пробелами. Может кто-нибудь порекомендовать, как это сделать на Linux? Любые предложения помогут.

+0

Кто голосовал, чтобы закрыть как принадлежит SU? Это хорошо установленный прецедент здесь, что sed - язык программирования, но примитивный. В любом случае на этот вопрос лучше всего ответить с помощью awk/perl-решения. – paxdiablo

+0

Имеет ли «(пробел») пробел, символ новой строки, пробел (пробел, символ новой строки, табуляция) или кратность одного или нескольких из них? –

+0

Кроме того, в вашем примере с желаемыми результатами следует не включать строки, которые говорят «nr 2», чтобы они соответствовали «имеют только« второе »несколько лайнеров из каждой секции»? –

ответ

0

Я бы пошел awk более sed. Создайте список, пока не нажмете /-+$/, а затем выведите раздел нескольких строк, который вы сохранили до каждой пунктирной линии.

EDIT: Я бы пошел perl до этого, но awk тоже весело.

0

Следующий сценарий perl сделает то, что вы хотите (я нахожу, что sed не так хорошо подходит для задач, охватывающих несколько строк).

#!/usr/bin/perl 

$first = 1; 
$skip = 2; 
while (<>) { 
    chomp; 
    $ln = $_; 
    if ($ln =~ /^-{58}$/) { 
     $skip = 2; 
     next; 
    } 
    if ($skip > 0) { 
     $skip--; 
     if ($skip == 0) { 
      if ($first) { 
       $first = 0; 
      } else { 
       print "\n"; 
      } 
     } 
     next; 
    } 
    if ($skip == 0) { 
     print $ln . "\n"; 
     if ($ln =~ /^$/) { 
      $skip = -1; 
     } 
    } 
} 

Это основан на предположении, что ваши (space) линий являются только пустыми строками. Если это не так, вам нужно будет отрегулировать шаблон /^$/ у основания, чтобы он соответствовал тому, что на самом деле.

Это, в основном, упрощенный государственный автомат, управляемый переменной $skip. Когда это положительно, вы пропускаете это множество строк (начинается с 2 и устанавливается на 2 для каждой линии ---).

Когда $skip достигает нуля, он остается там до тех пор, пока вы не получите пустую строку (вы эхом отдаете эти строки, когда идете). Когда вы получаете пустую строку, вы устанавливаете ее на -1 и останавливаете эхо строк.

Переменная $first - это немного взломать, чтобы гарантировать, что в вашем выходе нет конечной пустой строки.

Вот результат я получил от вашего входного файла:

multiple 
lines 
text 
(space) 
different 
multiple 
lines 
text 
(space) 
different 
multiple 
lines 
text 

который я считаю, что вы были после.

0

Редактировать: напечатать первую многострочную группу:

awk 'BEGIN {toggle=1} /^\(space)$/ {if (!toggle) print ""; toggle=!toggle; next} {if (! toggle) print}' file.txt 

Оригинал: напечатать вторую многострочную группу:

awk '/^\(space)$/ { accum=""; next} /^-+$/ {print accum; accum=""; next} {accum=accum"\n"$0}' file.txt 
+0

Я использовал «(пробел)» как литеральную строку, но вы можете изменить ее на '/^$/'для проверки пустой строки. –

-1

поглазеть

awk '{ print $2 }' RS="-\n" FS="\n\n" file 

выход

$ ./shell.sh 
multiple 
lines 
text 
different 
multiple 
lines 
text 
different 
multiple 
lines 
text 

эквивалент в Perl.

$\ = "\n"; 
$/ = "-\n"; 
while (<>) { 
    chomp; 
    ($f1,$f2) = split "\n\n", $_ ; 
    print $f2; 
} 
+0

Возможно, вам придется изменить это, поскольку он не выводит пустые строки. – paxdiablo

+0

Я оставлю это ОП в качестве упражнения. – ghostdog74

1
perl -00 -ne 'print if $.%2==0' 

-00 флаг устанавливает разделитель быть пустые строки.

 Смежные вопросы

  • Нет связанных вопросов^_^