2009-12-22 4 views
8

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

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

One 
Two 
Three 
Bravo 
Four 
Five 

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

One 
Two 
Three 

ответ

2

в Perl:

perl -nle '/B.*/ && last; print; ' source.txt 
+0

/B.*/ будет соответствовать что-нибудь, содержащее B, а не начиная с B. – rjh

+0

Вопрос не указывал, что «B» должен быть в начале строки. –

+0

Извините, вы правы - это зависит от нашей интерпретации. – rjh

5
sed '/^B/,$d' 

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

0

Если Perl является possibilty, вы могли бы сделать что-то вроде этого:

% perl -0ne 'if (/B.*/) { print $`; last }' INPUT_FILE 
+0

Кажется излишним читать весь файл в памяти, прежде чем что-либо делать. – ephemient

7

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

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

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

awk '/^B/{exit}NR>=10' file # start from line 10 
11

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

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

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

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

6
sed -n '1,/^B/p' 

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


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

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

/I3az/

+0

К сожалению, это печатает, включая строку «Браво», в то время как вопрос хочет исключить линию «Браво». – ndim

+0

Arghh! ... не правильно прочитал вопрос. Обновлено с обратным действием «! P» (т. Е. Print!) Для всего, что не между/^ B/и концом файла. Большое спасибо за обнаружение этого ndim. – draegtun

+0

Ах. '!' изменяет диапазон адресов так, чтобы он соответствовал только тому, где он не соответствовал, и наоборот. Он по-прежнему является частью диапазона адресов. Ну, '!' Был для меня новичком ... спасибо, что указали на меня. – ndim

2

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

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

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

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

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

Doing его в СЭД:

<command> | sed -n '1,/<regex>/p' 
+0

Оператор флип-флоп является одним из моих фаворитов, и эта ситуация является одним из немногих, которые я могу использовать. :) –

3

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

sed -n '/^Bravo/q;p' 
2

Ваша проблема является вариацией на ответ в perlfaq6: How can I pull out lines between two patterns that are themselves on different lines?.


Вы можете использовать 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 $. 
} 
0

один лайнер с основными командами оболочки:

head -`grep -n B file|head -1|cut -f1 -d":"` file