Мені потрібна допомога з Грепом, щоб почати з розділу


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з --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).
Байт командир

@ByteCommander yup, також можна зробити. Щойно використаний повний варіант для ясності
Сергій Колодяжний

1
@ByteCommander Який чудовий хакер. На жаль, це працює лише тому, що у назві файлу немає пробілів.
kasperd

@kasperd О так, ти маєш рацію. У такому випадку вам доведеться повернутися до початкової команди Серга grep "yellow" -A $(wc -l < "my colors.txt") "my colors.txt".
Байт-командир


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 знаходить лише цілі рядки, що дорівнюють "жовтому", він не виявляє, наприклад, рядки типу "більш жовті".
Байт командир

@ByteCommander З прикладу ОП я думаю, що зрозуміло, що вони хочуть відповідати лише yellowв рядку. Так само якщо це не так, нам потрібно змінити python
альго

Так, звісно. Це все одно не було критики, а лише натяк на покращення відповіді. Хтось ще, хто читає це, може припустити, що код працює як grepі не відповідає лише повним рядкам. Я підтримав btw.
Байт командир

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.