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 есть флаг. Распечатайте строки после вашего матча. Однако вам нужно указать, сколько строк вы хотите после матча. Мне интересно, есть ли что-то, чтобы обойти эту проблему. Как:

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

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

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

Ответ 1

Awk

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

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

Этот script имеет две части:

/yahoo/ { y = 1; next }
y

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

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

y != 0 { print }

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

Sed

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

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

Ответ 2

Это намного проще сделать с 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 elete the line" (а затем, неявно, печатать все остальное, обратите внимание, что -n не используется в этот раз).

Ответ 3

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

Или игра в гольф

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

Результат

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

Ответ 4

Это проще всего сделать в Perl:

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

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

Ответ 5

с помощью script

#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