5

У меня есть текстовый файл, похожий на этот:

line 1
line 2A
line 3
line 4A
line 5

Я хочу "grep" от "строки 2A" до конца файла, что-то вроде этого

cat file.txt|some_grep "line 2A"

Кроме того, я хочу "grep" от "строки 2A" до следующей строки, которая содержит "A", что-то вроде этого

cat file.txt| some_grep "A"

Я хочу, чтобы это распечатать:

line 2A
line 3
line 4A

Какая команда может помочь мне достичь этого?

5 ответов5

3

Я хочу "grep" от "строки 2A" до конца файла:

sed -n '/2A/,$p'
  • -n: подавить вывод sed умолчанию
  • / 2A/: выходные строки из первой, содержащей "2A"
  • $: в конец файла

Я хочу "grep" от "строки 2A" до следующей строки, которая содержит "A":

sed -n '/2A/,/A/p'
  • /A/: вывод до строки, содержащей "A"

Я хочу "grep" от первой строки, содержащей "A", до следующей:

printf "/A\n.+1,/A/p\nq" | ed -s

$ > foo echo "line 1
line 2A
line 3
line 4A
line 5"

$ sed -n '/2A/,$p' foo
line 2A
line 3
line 4A
line 5

$ sed -n '/2A/,/A/p' foo
line 2A
line 3
line 4A

$ printf "/A\n.+1,/A/p\nq" | ed -s foo
line 2A
line 3
line 4A
2

(дополнено комментарием)

awk имеет возможность выбирать «диапазоны» строк, которые идеально соответствуют этой потребности, как описано в руководстве GNU-awk (gawk). (Эта функция работает в других awk но руководство по gawk легко связать.)

awk '/line 2A/,0' печатает строки, начинающиеся с первой строки , совпадающей со line 2A и продолжающейся до конца ввода, поскольку 0 - это условие, которое никогда не выполняется.

awk '/line 2A/,/A/&&!/line 2A/' начинает печать со строки, которая соответствует line 2A и останавливается после строки, которая соответствует A но НЕ является line 2A (и, следовательно, не может быть той же линией, что и начальная строка). Он начнется снова в следующей line 2A и т. Д .; если вы хотите предотвратить это, есть несколько более сложные способы сделать это.

Если строки остановки всегда имеют какой-либо символ, отличный от 2 перед A это можно упростить до awk '/line 2A/,/[^2]A/' который останавливается после строки, которая соответствует любому символу, кроме 2, за которым следует A Вы можете захотеть изменить это, например, остановиться на любой-однозначной-A, отличной от 2A, но не на другой. Как, например, WHAT ; для этого может быть условие остановки ,/line [013-9]A/ .

1

Я думаю, что лучший способ - использовать grep в сочетании с cut и tail . Во-первых, используйте grep, чтобы получить строку, в которой находится нужная строка (-n для вывода номера строки; -m 1 для прекращения поиска после первого совпадения):

grep -n -m 1 "somestring" filename.txt

Это выводит номер строки и саму строку. Чтобы вырезать строку, мы используем cut (-f1: поле вывода первого; -d: использовать ":" в качестве разделителя):

grep -n -m 1 "somestring" filename.txt | cut -f1 -d:

Далее мы используем вывод этой команды в качестве параметра в tail. Обычно tail печатает последние k строк, но используя -n +k , мы получаем tail для печати от строки k и далее. Общая команда:

tail -n +`grep -n -m 1 "somestring" filename.txt | cut -f1 -d:` filename.txt

Чтобы выводить строки до somestring строки, используйте head вместо tail и -n -# вместо -n +# . Вы также можете объединить оба, чтобы получить строки от одной строки до другой.

0

Метод sed - это правильный путь, но что, если вы хотите сохранить верхние строки, а не grep их?

Вот способ:

{ head -1 file.txt ; sed 1d file.txt | grep <whatever> ;}

Что тут происходит?

Сначала мы выплевываем верхнюю строку (head -1 file.txt). Затем удаляем верхнюю строку (sed 1d file.txt) и просто добавляем grep.

Все это обернуто {..;}, так что вы можете затем передать или перенаправить заголовок и собранное тело вместе. Как это:

{head -1 file.txt; sed 1d file.txt | grep;}> newfile.txt

Если вы хотите пропустить первые 10 строк, измените его на этот

{head -10 file.txt; sed 1,10d file.txt | grep;}

0

Пожалуйста, попробуйте код ниже -

sed -n '6,$p' infile

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .