Как я могу удалить текст в начале файла с помощью регулярных выражений?
У меня есть куча файлов, которые содержат полустандартный заголовок. То есть внешний вид очень похож, но текст несколько меняется.
Я хочу удалить этот заголовок из всех файлов.
Просматривая файлы, я знаю, что то, что я хочу удалить, заключено между похожими словами.
Так, например, у меня есть:
Foo bar...some text here...
more text
Foo bar...I want to keep everything after this point
Я попробовал эту команду в Perl:
perl -pi -e "s/\A.*?Foo.bar*?Foo.bar//simxg" 00ws110.txt
Но это не работает. Я не эксперт по регулярным выражениям, но надеюсь, что кто-то знает, как в основном удалить фрагмент текста из начала файла на основе совпадения текста, а не количества символов...
4 ответа
По умолчанию, ARGV
(ака <>
который используется за кулисами -p
) читает только одну строку за раз.
обходные:
Отозвать
$/
, который говорит Perl читать весь файл за раз.perl -pi -e "BEGIN{undef$/}s/\A.*?Foo.bar*?Foo.bar//simxg" 00ws110.txt
BEGIN
необходимо, чтобы этот код выполнялся до первого чтения.использование
-0
, который устанавливает$/ = "\0"
,perl -pi -0 -e "s/\A.*?Foo.bar*?Foo.bar//simxg" 00ws110.txt
Воспользуйтесь оператором триггера.
perl -ni -e "print unless 1 ... /^Foo.bar/'
Это пропустит печать, начиная со строки 1 до
/^Foo.bar/
,
Если ваш заголовок занимает более одной строки, вы должны указать Perl, сколько читать. Если файлы невелики по сравнению с памятью, вы можете просто захлопнуть весь файл в память:
perl -0777pi.orig -e 's/your regex/your replace/s' file1 file2 file3
-0777
опция устанавливает perl в режим slurp, поэтому $_
будет держать каждый целый файл каждый раз через цикл. Кроме того, всегда не забывайте устанавливать расширение для резервного копирования. Если вы этого не сделаете, вы можете обнаружить, что вы удалили свои данные случайно и не можете вернуть их. Увидеть perldoc perlrun
для дополнительной информации.
Учитывая информацию из комментариев, похоже, что вы пытаетесь убрать все раздражающие вещи с обложки книги Project Gutenberg. Если вы понимаете все связанные с этим вопросы авторского права, вы сможете избавиться от основного вопроса, например:
perl -ni.orig -e 'print unless 1 .. /^\*END/' 00ws110.txt
Заголовок проекта Гутенберга заканчивается
*END*THE SMALL PRINT! FOR PUBLIC DOMAIN ETEXTS*Ver.04.29.93*END*
Более безопасное регулярное выражение будет учитывать *END*
в конце строки, но я ленивый.
Возможно, я неверно истолковываю то, что вы просите, но для меня это выглядит так просто:
perl -ni -e 'print unless 1..($. > 1 && /^Foo bar/)'
Ну вот! Это заменяет первую строку файла:
use Tie::File;
tie my @array,"Tie::File","path_to_file" or die("can't tie the file");
$array[0] =~s/text_i_want_to_replace/replacement_text/gi;
untie @array;
Вы можете работать с массивом, и вы увидите изменения в массиве. Вы можете удалить элементы из массива, и это сотрет строку из файла. Применение подстановки к элементам заменит текст из строк.
Если вы хотите удалить первые две строки и сохранить что-то от третьей, вы можете сделать что-то вроде этого:
# tie the @array before this
shift @array;
shift @array;
$array[0]=~s/foo bar\.\.\.//gi;
# untie the @array
и это будет делать именно то, что вам нужно!