Вопрос

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

Обычно это

*** Start (more text here)

И заканчивается

*** Finish (more text here)

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

Ах да, конечно, это сервер Linux, поэтому у меня есть Perl, sed, awk, grep и т. д.

Это было полезно?

Решение

Попробуйте триггер! " .. " Оператор.

# flip-flop.pl
use strict;
use warnings;

my $start  = qr/^\*\*\* Start/;
my $finish = qr/^\*\*\* Finish/;

while ( <> ) {
    if ( /$start/ .. /$finish/ ) {
        next  if /$start/ or /$finish/;
        print 

Попробуйте триггер! " .. " Оператор.

 $ perl -i'copy_*' flip-flop.pl data.txt 

Затем вы можете использовать ключ -i perl для обновления ваших файлов следующим образом .....

<*>

... который изменяет data.txt, но предварительно делает копию как " copy_data.txt ".

; } }

Затем вы можете использовать ключ -i perl для обновления ваших файлов следующим образом .....

<*>

... который изменяет data.txt, но предварительно делает копию как " copy_data.txt ".

Другие советы

GNU coreutils - ваш друг ...

csplit inputfile %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}

В результате вы получите нужный файл в формате xx00 . Вы можете изменить это поведение с помощью параметров - префикс , - суффикс и - цифры , но посмотрите руководство для себя. Поскольку csplit предназначен для создания нескольких файлов, невозможно создать файл без суффикса, поэтому вам придется выполнить перезапись вручную или с помощью сценария:

csplit $1 %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}
mv -f xx00 $1

Добавляйте циклы по своему желанию.

Чтобы получить заголовок :

cat yourFileHere | awk '{if (d > 0) print 
cat yourFileHere | awk '/.*Finish.*/ {d = 1} {if (d < 1) print 
cat yourFileHere | awk '/.*Start.*/ {d = 1; next} /.*Finish.*/ {d = 0; next} {if (d > 0) print 
csplit yourFileHere /Start/ /Finish/
}'
}'
} /.*Start.*/ {d = 1}'

Чтобы получить нижний колонтитул :

<*>

Чтобы получить файл из верхнего / нижнего колонтитула , как вы хотите:

<*>

Есть еще один способ, с помощью команды csplit, вы должны попробовать что-то вроде:

<*>

И просмотрите файлы с именем «xxNN», где NN - это номер, также посмотрите man-страница csplit .

Может быть?От начала до завершения с неудалением.

$ sed -i '/^\*\*\* Start/,/^\*\*\* Finish/d!' *

или... менее уверен в этом... но, если это сработает, следует также удалить строки начала и финиша:

$ sed -i -e '/./,/^\*\*\* Start/d' -e '/^\*\*\* Finish/,/./d' *

d! может зависеть от сборки sed у вас есть - не уверен.
И я написал это полностью на (вероятно, плохой) памяти.

Быстрый взлом Perl, не проверенный. Я недостаточно хорошо знаю sed или awk, чтобы получить такой эффект, но мне было бы интересно узнать, как это будет сделано.

#!/usr/bin/perl -w
use strict;
use Tie::File;
my $Filename=shift;  
tie my @File, 'Tie::File', $Filename or die "could not access $Filename.\n";  
while (shift @File !~ /^\*\*\* Start/) {};  
while (pop @File !~ /^\*\*\* Finish/) {};  
untie @File;  

Некоторые из примеров в perlfaq5: как изменить, удалить или вставить строку в файл или добавить в начало файла? может помочь. Вам придется адаптировать их к вашей ситуации. Кроме того, ответ оператора триггера Леона - идиоматический способ сделать это в Perl, хотя вам не нужно изменять файл на месте, чтобы использовать его.

Решение Perl, которое перезаписывает исходный файл.

#!/usr/bin/perl -ni
if(my $num = /^\*\*\* Start/ .. /^\*\*\* Finish/) {
    print if $num != 1 and $num + 0 eq $num;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top