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