Мне нужна помощь с Grep, чтобы начать в разделе

8

У меня есть несколько текстовых файлов, из которых я хочу получить фрагмент кода. Цель, которую я пытаюсь достичь, состоит в том, чтобы запустить представление с определенной строки и затем прочитать все, что ниже. Например. В тексте ниже, как я могу просмотреть текстовый файл в начальной точке желтого цвета. Я хочу просмотреть содержимое «желтого», а также все, что находится под ним, независимо от того, что это за содержимое.

green
blue
cyan
magenta
purple
brown
yellow
red
orange
more orange
more blue
this is enough
Джон Смит
источник

Ответы:

9

Использование AWKAWK - это самое простое, что можно получить:

awk '/yellow/,0' textfile.txt

Пробный прогон

$ awk '/yellow/,0' textfile.txt                                
yellow
red
orange
more orange
more blue
this is enough

Grep

Вы также можете использовать grepс --after-contextопцией, чтобы напечатать определенное количество строк после матча

grep 'yellow' --after-context=999999  textfile.txt

Для автоматической настройки контекста вы можете использовать $(wc -l textfile.txt). Основная идея заключается в том, что если у вас есть самая первая строка в качестве совпадения и вы хотите напечатать все после этого совпадения, вам нужно знать количество строк в файле минус 1. К счастью, --after-contextне будет выдавать ошибки о количестве линий, так что вы могли бы дать ему номер полностью вне диапазона, но в случае, если вы не знаете, общее количество строк будет делать

$ grep 'yellow' --after-context=$(wc -l < textfile.txt) textfile.txt
yellow
red
orange
more orange
more blue
this is enough

Если вы хотите сократить команду --after-context- это та же опция, что -Aи $(wc -l textfile.txt), расширится до количества строк, за которыми следует имя файла. Таким образом, вы печатаете textfile.txtтолько один раз

grep "yellow" -A $(wc -l textfile.txt)

питон

skolodya@ubuntu:$ ./printAfter.py textfile.txt                                 
yellow
red
orange
more orange
more blue
this is enough

DIR:/xieerqi
skolodya@ubuntu:$ cat ./printAfter.py                                          
#!/usr/bin/env python
import sys

printable=False
with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
           printable=True
        if printable:
           print line.rstrip('\n')

Или альтернативно без printableфлага

#!/usr/bin/env python
import sys

with open(sys.argv[1]) as f:
     for line in f:
        if "yellow" in line:
          for lines in f: # will print remaining lines
             print lines.rstrip('\n')
          exit()
Сергей Колодяжный
источник
Вы можете упростить grepкоманду до grep "yellow" -A $(wc -l textfile.txt).
Byte Commander
@ByteCommander да, можно сделать и так. Просто использовал полный вариант для наглядности
Сергей Колодяжный
1
@ByteCommander Какой прекрасный хак. К сожалению, это работает только потому, что в имени файла нет пробелов.
Касперд
@ kasperd Ах, да, ты прав. В этом случае вам придется вернуться к первоначальной команде Серга grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt".
Byte Commander
5

Вы можете сделать это:

awk '/yellow/{f=1}f' file

где «файл» - это имя файла, содержащего ваш текст.

Pilot6
источник
Великие умы думают одинаково> :)
Сергей Колодяжный
5

Не grep, но используя sed:

sed -n '/^yellow$/,$p' file
  • -n: запрещает печать
  • /^yellow$/,$: диапазон адресов от первого вхождения строки, точно совпадающей yellowс последней строкой включительно
  • p: печатает строки в диапазоне адресов
% sed -n '/^yellow$/,$p' file
yellow
red
orange
more orange
more blue
this is enough
кос
источник
5

Поздно на вечеринку :)

Использование grep:

grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
  • -P позволяет нам использовать Perl-совместимый Regex

  • -z делает входной файл разделенным ASCII NUL, а не переводом строки

  • -o занимает только желаемую порцию

  • (?s)является модификатором DOTALL, позволяет нам сопоставить символ новой строки с помощью токена .(любой символ)

  • В \n\K, \nсоответствует новая строка, \Kсбрасывает матч

  • yellow\n.*совпадения, yellowза которыми следует символ новой строки, и все, что после этого, также выбирается и отображается в выходных данных.

Пример:

% grep -Pzo '(?s)\n\Kyellow\n.*' file.txt
yellow
red
orange
more orange
more blue
this is enough

Используя немного python:

#!/usr/bin/env python2
with open('file.txt') as f:
    lines = f.readlines()
    print ''.join(lines[lines.index('yellow\n'):])
  • lines список, содержащий все строки файла (также с завершающими символами новой строки)

  • lines.index('yellow\n')дает нам самый низкий индекс, linesгде yellow\nнаходится

  • lines[lines.index('yellow\n'):]будет использовать нарезку списка, чтобы получить часть, начиная с yellow\nконца

  • join объединит элементы списка для вывода в виде строки

heemayl
источник
Хорошо, но вы должны отметить, что код Python находит только целые строки, равные «желтым», он не обнаруживает, например, такие строки, как «более желтые».
Byte Commander
@ByteCommander Из примера OP я думаю, что ясно, что они хотят совпадать просто yellowв строке ... Также, если это не так, то нам нужно изменить python
алгоритм
Да, конечно. В любом случае, это была не критика, а лишь намек на улучшение ответа. Кто-то еще, читающий это, может предположить, что код работает как grepи не совпадает только с полными строками. Я проголосовал, кстати.
Byte Commander
4

Так как вопрос касается просмотра файла, всегда есть хорошая

less +/yellow file
steeldriver
источник
Не знаю, lessмогу это сделать. Очень хорошо !
Сергей Колодяжный