изменить текстовый файл - PullRequest
2 голосов
/ 22 апреля 2011

Мне нужно изменить все файлы с расширением «.txt» в каталоге следующим образом:

удалить все текстовые строки, начинающиеся со строки, которая начинается с «xxx», и строки, которая заканчиваетсяс "xxx" включительно.

Я знаю, как это сделать на Java или C ++, но может кто-нибудь показать мне простой скрипт, который может это сделать?

Ответы [ 3 ]

8 голосов
/ 22 апреля 2011

Я предполагаю, что вы хотите потерять начало и конец, и эти слова появляются сами по себе в строках, которые вы хотите потерять.

perl -ni.bak -e 'print unless /^start$/../^end$/' *.txt

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

2 голосов
/ 22 апреля 2011

Не то, чтобы с ответом @ btilly было что-то не так - на самом деле, я бы сам сделал это по-своему - но просто чтобы показать вам, что Есть больше, чем один способ сделать это , вы также можете использовать замена:

% perl -i.save -0777 -pe 's/^start.*end$//gsm' *.txt

Это оставит вам дополнительную последовательность новой строки в конце, но это работает, если конец в EOF, и нет новой строки. Вы также можете принять это во внимание следующим образом:

% perl -i.save -0777 -pe 's/^start.*end$\R?//gsm' *.txt

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

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

Еще одна приятная особенность использования Perl для этого заключается в том, что он очень легко работает и с файлами данных UTF-8:

bash-3.2$ cat /tmp/data
     1  fee 
     2  commencé
     3  fie foo
     4  fum
     5  terminé
     6  beat on 
     7  the drum

bash-3.2$ perl -Mutf8 -CSD -nle 'print unless /commencé/ .. /terminé/' /tmp/data
     1  fee 
     6  beat on 
     7  the drum

bash-3.2$ perl -i.guardé -Mutf8 -CSD -nle 'print unless /commencé/ .. /terminé/' /tmp/data

bash-3.2$ cat /tmp/data
     1  fee 
     6  beat on 
     7  the drum

bash-3.2$ cat /tmp/data.guardé 
     1  fee 
     2  commencé
     3  fie foo
     4  fum
     5  terminé
     6  beat on 
     7  the drum

Et voilà! :)

Это одна из тех проблемных областей, где Perl особенно подходит для чрезвычайно коротких, простых, читаемых и поддерживаемых ответов. Это действительно мощный инструмент Unix.

Очевидно, что вы никогда не будете подходить к такого рода операциям с мощным инструментом из Java или C ++. Я подозреваю, что Ruby может сделать что-то подобное, но я думаю, что Python слишком далек от стиля Unix, чтобы дать как лаконичный и простой ответ.

Кроме того, он также работает довольно быстро: не совсем так быстро, как C, но, конечно, намного, намного быстрее, чем какой-то сильно медленный сценарий оболочки. Ну, по крайней мере, если вы делаете обработку аналогичным образом, то есть. Чтение всего в память никогда не масштабируется, но для мелочей это нормально. Кроме того, инструменты оболочки, как правило, бомбардируют файлы с двоичными данными в них или очень длинными строками, поэтому вы не всегда можете полагаться на них в таких вещах, особенно в переносимой, кроссплатформенной форме. И почти никто из них не работает надежно с Юникодом, что в наши дни является реальной необходимостью.

0 голосов
/ 22 апреля 2011
ruby -i.bak -ne 'print unless /^start/.../^end/' *.txt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...