Как извлечь строки текста из файла?
Вопрос
У меня есть каталог, полный файлов, и мне нужно удалить из них верхние и нижние колонтитулы.Все они имеют переменную длину, поэтому использование головы или хвоста не сработает.В каждом файле есть строка, которую я могу найти, но я не хочу включать ее в результаты.
Обычно это
*** 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;
}