Как отобразить данные от начала файла до первого появления регулярного выражения? - PullRequest
8 голосов
/ 22 декабря 2009

Как отобразить данные от начала файла до первого появления регулярного выражения?

Например, если у меня есть файл, который содержит:

One
Two
Three
Bravo
Four 
Five

Я хочу начать отображение содержимого файла, начиная со строки 1 и заканчивая, когда я нахожу строку «B *». Таким образом, результат должен выглядеть следующим образом:

One
Two
Three

Ответы [ 11 ]

11 голосов
/ 22 декабря 2009

perl -pe 'last if /^B/' source.txt

Объяснение: ключ -p добавляет цикл вокруг кода, превращая его в следующее:

while ( <> ) {
    last if /^B.*/;  # The bit we provide
    print;
}

Последнее ключевое слово немедленно покидает окружающий цикл, если выполняется условие - в этом случае / ^ B /, что указывает на то, что строка начинается с B.

7 голосов
/ 22 декабря 2009

если его с начала файла

awk '/^B/{exit}1' file

, если вы хотите начать с определенного номера строки

awk '/^B/{exit}NR>=10' file # start from line 10
6 голосов
/ 22 декабря 2009
sed -n '1,/^B/p'

Печать от строки 1 до / ^ B / (включительно). -n подавляет эхо по умолчанию.


Обновление: Оппс .... не хотел "Браво", поэтому вместо этого необходимо обратное действие; -)

sed -n '/^B/,$!p'  

/ I3az /

5 голосов
/ 22 декабря 2009
sed '/^B/,$d'

Прочитайте это следующим образом: Удалите (d) все строки, начинающиеся с первой строки, которая начинается с буквы "B" (/^B/), вплоть до последней строки ($).

3 голосов
/ 22 декабря 2009

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

sed -n '/^Bravo/q;p'
2 голосов
/ 23 декабря 2009

Ваша проблема - это вариант ответа в perlfaq6 : Как вытащить линии между двумя шаблонами, которые сами находятся на разных линиях? .


Вы можете использовать несколько экзотический оператор Perl .. (задокументировано в perlop):

perl -ne 'print if /START/ .. /END/' file1 file2 ...

Если вы хотите текст, а не строки, вы бы использовали

perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' file1 file2 ...

Но если вы хотите, чтобы вложенные вхождения START и END были вложенными, вы столкнетесь с проблемой, описанной в вопросе в этом разделе о сопоставлении сбалансированного текста.

Вот еще один пример использования ..:

while (<>) {
    $in_header =   1  .. /^$/;
    $in_body   = /^$/ .. eof;
# now choose between them
} continue {
    $. = 0 if eof;  # fix $.
}
2 голосов
/ 22 декабря 2009

Просто делюсь некоторыми ответами, которые я получил:

Печатайте данные, начиная с первой строки, и продолжайте, пока мы не найдем совпадение с регулярным выражением, затем остановите:

<command> | perl -n -e 'print "$_" if 1 ... /<regex>/;'

Печатайте данные, начиная с первой строки, и продолжайте, пока не найдем совпадение с регулярным выражением, НО не отображайте строку, соответствующую регулярному выражению:

<command> | perl -pe '/<regex>/ && exit;'

Делаем это в седе:

<command> | sed -n '1,/<regex>/p'
2 голосов
/ 22 декабря 2009

в Perl:

perl -nle '/B.*/ && last; print; ' source.txt
1 голос
/ 22 декабря 2009

Вот Perl однострочный:

perl -pe 'last if /B/' file
0 голосов
/ 22 января 2010

один вкладыш с основными командами оболочки:

head -`grep -n B file|head -1|cut -f1 -d":"` file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...