[ Редакционная вставка: Возможный дубликат того же плаката более ранний вопрос?]
Привет, мне нужно извлечь из файла:
first
second
third
используя команду grep, следующую строку:
second
third
Как должна выглядеть команда grep?
[ Редакционная вставка: Возможный дубликат того же плаката более ранний вопрос?]
Привет, мне нужно извлечь из файла:
first
second
third
используя команду grep, следующую строку:
second
third
Как должна выглядеть команда grep?
Вместо grep
вы можете использовать pcregrep
, который поддерживает многострочные шаблоны
pcregrep -M 'second\nthird' file
-M
позволяет шаблону соответствовать нескольким строкам.
Ваш аннотация вопроса bash grep newline "означает, что вы хотите совместить последовательность second\nthird
символов, то есть что-то, содержащее в ней новую строку.
Так как grep работает на "строках", и эти две разные строки, вы не сможете сопоставить их таким образом.
Итак, я бы разделил его на несколько задач:
вы сопоставляете строку, содержащую "вторую", и выводите строку, которая соответствует, и следующую строку:
grep -A 1 "second" testfile
вы переводите каждую другую строку новой строки в последовательность, которая не будет присутствовать во входе. Я думаю, что самый простой способ сделать это - использовать perl:
perl -npe '$x=1-$x; s/\n/##UnUsedSequence##/ if $x;'
вы выполняете grep в этих строках, на этот раз, ища строку ##UnUsedSequence##third
:
grep "##UnUsedSequence##third"
вы разворачиваете неиспользуемые последовательности обратно в новые строки, sed может быть самым простым:
sed -e 's/##UnUsedSequence##/\n'
Итак, получившаяся команда pipe, чтобы сделать то, что вы хотите, будет выглядеть так:
grep -A 1 "second" testfile | perl -npe '$x=1-$x; s/\n/##UnUsedSequence##/ if $x;' | grep "##UnUsedSequence##third" | sed -e 's/##UnUsedSequence##/\n/'
Не самый элегантный на сегодняшний день, но должен работать. Мне любопытно узнать о лучших подходах, хотя - должно быть что-то.
Я не думаю, что grep - это способ сделать это.
Если вы просто хотите удалить первую строку из любого файла (чтобы обобщить ваш вопрос), я бы использовал sed.
sed '1d' INPUT_FILE_NAME
Это приведет к отправке содержимого файла в стандартный вывод с удалением первой строки.
Затем вы можете перенаправить стандартный вывод в другой файл, чтобы получить результаты.
sed '1d' INPUT_FILE_NAME > OUTPUT_FILE_NAME
Это должно сделать это.
Если вам нужно использовать grep и просто не хотите отображать строку с первой на ней, попробуйте следующее:
grep -v first INPUT_FILE_NAME
Передавая переключатель -v, вы сообщаете grep, чтобы показать вам все , но выражение, которое вы передаете. По сути, покажите мне все, кроме строк с первым в них.
Однако недостатком является то, что файл с несколькими первыми в нем не отображает эти другие строки и может не соответствовать тому, что вы ожидаете.
Чтобы шунтировать результаты в новый файл, попробуйте следующее:
grep -v first INPUT_FILE_NAME > OUTPUT_FILE_NAME
Надеюсь, что это поможет.
Я действительно не понимаю, что вы хотите совместить. Я бы не использовал grep, но одно из следующего:
tail -2 file # to get last two lines
head -n +2 file # to get all but first line
sed -e '2,3p;d' file # to get lines from second to third
(не уверен, насколько это стандартно, он отлично работает в GNU-инструментах)
Линия? Или строки?
Try
grep -E -e '(second|third)' filename
Изменить: grep ориентирован на линию. вам придется использовать Perl, sed или awk для выполнения соответствия шаблону по строкам.
BTW -E сообщает grep, что регулярное выражение расширено RE.
Значит, вы просто не хотите, чтобы строка содержала "первый"? -v
инвертирует результаты grep.
$ echo -e "first\nsecond\nthird\n" | grep -v first
second
third
grep -A1 "second" | grep -B1 "third" работает красиво, и если у вас несколько совпадений, он даже избавится от разделителя оригинала - match
grep -E '(second|third)' /path/to/file
egrep -w 'second|third' /path/to/file
вы можете использовать
$ grep -1 third filename
это будет печатать строку с совпадением и одну строку до и после. Поскольку "третий" находится в последней строке, вы получаете последние две строки.
Мне нравится notnoop answer, но на основе AndrewY answer (что лучше для тех, у кого нет pcregrep, но слишком сложно), вы можете просто сделать:
RESULT=`grep -A1 -s -m1 '^\s*second\s*$' file | grep -s -B1 -m1 '^\s*third\s*$'`
grep -v '^first' filename
Если флаг -v инвертирует соответствие.