grep +A: распечатать все после матча

Привет у меня есть файл, содержащий список URL-адресов, выглядит следующим образом:

file1:

http://www.google.com
http://www.bing.com
http://www.yahoo.com
http://www.baidu.com
http://www.yandex.com
....

Я хочу получить все записи после: http://www.yahoo.com/, результаты выглядят так:

file2:

http://www.baidu.com
http://www.yandex.com
....

Я знаю, что могу использовать grep, чтобы найти номер строки, где лежит yahoo.com, используя

$grep -n 'http://www.yahoo.com' file1
3 http://www.yahoo.com

Но я не знаю, как получить файл после строки № 3. Кроме того, я знаю, что в grep есть флаг -A выводить строки после вашего совпадения. Однако вам нужно указать, сколько строк вы хотите после матча. Мне интересно, есть ли что-то, чтобы обойти эту проблему. Подобно:

PSEUDO CODE:
$ grep -n 'http://www.yahoo.com' -A all file1 > file2 

Я знаю, что мы могли бы использовать номер строки, который я получил, и wc -l, чтобы получить количество строк после yahoo.com, однако... кажется довольно слабым.

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

5 ответов

Решение

Awk

Если вы не возражаете против использования awk:

awk '/yahoo/{y=1;next}y' data.txt

Этот скрипт состоит из двух частей:

/yahoo/ { y = 1; next }
y

Первая часть утверждает, что если мы встречаем строку с yahoo, мы устанавливаем переменную y=1, затем пропускаем эту строку (next команда перейдет к следующей строке, пропуская дальнейшую обработку текущей строки). Без next Команда, строка Yahoo будет напечатана.

Вторая часть - это короткая рука для:

y != 0 { print }

Это означает, что для каждой строки, если переменная y отлична от нуля, мы печатаем эту строку. В awk, если вы ссылаетесь на переменную, эта переменная будет создана и будет либо нулевой, либо пустой строкой, в зависимости от контекста. До встречи с yahoo переменная y равна 0, поэтому скрипт ничего не печатает. После встречи yahoo, y равен 1, поэтому каждая строка после этого будет напечатана.

Sed

Или, используя sed, следующее удалит все, вплоть до строки с yahoo:

sed '1,/yahoo/d' data.txt 

Это намного проще сделать с sed чем grep, sed может применять любую из однобуквенных команд для широкого диапазона строк; общий синтаксис для этого

START , STOP COMMAND

кроме как без пробелов. START а также STOP каждый может быть числом (означающим "номер строки N", начиная с 1); знак доллара (означающий "конец файла") или регулярное выражение, заключенное в косые черты, что означает "первая строка, соответствующая этому регулярному выражению". (Точные правила немного сложнее; GNU sed Руководство имеет более подробную информацию.)

Итак, вы можете делать то, что вы хотите, так:

sed -n -e '/http:\/\/www\.yahoo\.com/,$p' file1 > file2

-n означает "ничего не печатать, если специально не сказано", и -e директива означает "с первого появления строки, которая соответствует регулярному выражению /http:\/\/www\.yahoo\.com/ в конец файла, p ечать ".

Это будет включать строку с http://www.yahoo.com/ на это в выводе. Если вы хотите все после этой точки, но не в самой строке, самый простой способ сделать это - инвертировать операцию:

sed -e '1,/http:\/\/www\.yahoo\.com/d' file1 > file2

что означает "для строки 1 до первой строки, соответствующей регулярному выражению /http:\/\/www\.yahoo\.com/, d выбрать строку " (а затем, неявно, напечатать все остальное; обратите внимание, что -n не используется в этот раз).

awk '/yahoo/ ? c++ : c' file1

Или в гольф

awk '/yahoo/?c++:c' file1

Результат

http://www.baidu.com
http://www.yandex.com

Это легче всего сделать в Perl:

perl -ne 'print unless 1 .. m(http://www\.yahoo\.com)' file

Другими словами, выведите все строки, которые не находятся между строкой 1 и первым появлением этого шаблона.

Используя скрипт

#get index of yahoo word
index=`grep -n "yahoo" filepath | cut -d':' -f1`
#get total number of lines in file
totallines=`wc -l filepath | cut -d' ' -f1`
#subtract totallines with index
result=`expr $total - $index`
#gives the desired output
grep -A $result "yahoo" filepath
Другие вопросы по тегам