Мне нужна помощь с 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

Не 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 объединит элементы списка для вывода в виде строки


Хорошо, но вы должны отметить, что код Python находит только целые строки, равные «желтым», он не обнаруживает, например, такие строки, как «более желтые».
Byte Commander

@ByteCommander Из примера OP я думаю, что ясно, что они хотят совпадать просто yellowв строке ... Также, если это не так, то нам нужно изменить python
алгоритм

Да, конечно. В любом случае, это была не критика, а лишь намек на улучшение ответа. Кто-то еще, читающий это, может предположить, что код работает как grepи не совпадает только с полными строками. Я проголосовал, кстати.
Byte Commander

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.