grep, чтобы вернуть Nth и Mth строки до и после матча

Вы также можете попробовать:

dpkg -l | egrep -i 'jre|java|jdk'
11
задан 10 May 2018 в 22:25

15 ответов

Если:

cat file
a
b
c
d
e
f match
g
h
i match
j
k
l
m
n
o

Затем:

awk '
    {line[NR] = $0} 
    /match/ {matched[NR]} 
    END {
        for (nr in matched)
            for (n=nr-5; n<=nr+5; n+=5) 
                print line[n]
    }
' file
a
f match
k
d
i match
n
13
ответ дан 22 May 2018 в 10:49
  • 1
    +1, но не могли бы вы объяснить семантику /match/ {matched[NR]}? Я никогда не видел массив или переменную как целую команду. Помещает ли он текущий номер записи каждой согласованной строки в массив. – Joe 17 May 2018 в 06:51
  • 2
    Это awk oddity: если вы ссылаетесь на элемент массива без назначения, этот ключ добавляется в массив (без значения). Затем этот ключ появляется в выражении key in array. То, что я делаю, это запоминание номеров строк, где отображается шаблон – glenn jackman 17 May 2018 в 14:45

Если:

cat file a b c d e f match g h i match j k l m n o

Затем:

awk ' {line[NR] = $0} /match/ {matched[NR]} END { for (nr in matched) for (n=nr-5; n<=nr+5; n+=5) print line[n] } ' file a f match k d i match n
13
ответ дан 17 July 2018 в 14:39

Если:

cat file a b c d e f match g h i match j k l m n o

Затем:

awk ' {line[NR] = $0} /match/ {matched[NR]} END { for (nr in matched) for (n=nr-5; n<=nr+5; n+=5) print line[n] } ' file a f match k d i match n
13
ответ дан 20 July 2018 в 14:42

Это невозможно сделать только с помощью grep. Если параметр ed имеет значение:

ed -s file << 'EOF' 
g/match/-5p\
+5p\
+5p
EOF  

В сценарии в основном говорится: для каждого совпадения / match /, напечатайте линию 5 строк до этого, затем 5 строк после этого, затем 5 строк после что.

7
ответ дан 22 May 2018 в 10:49
  • 1
    @ubashu Считаете ли вы, что это будет более полезно для OP, дающего простую квартиру, «это невозможно сделать с помощью grep»? Я предоставляю то, что считаю хорошей альтернативой решению проблемы OP. Из Справочного центра: «В чем конкретно заключается вопрос? Убедитесь, что ваш ответ предусматривает это - или жизнеспособную альтернативу. Ответ может быть «не делать этого», но он также должен включать «попробуйте это вместо». & Quot; – JoL 11 May 2018 в 03:16
  • 2
    ed является всегда ответом, потому что ed является стандартным текстовым редактором. – dessert 11 May 2018 в 11:28
  • 3
    @ubashu Хотя это не ответ grep, ответ «Вы не можете сделать это с X, но вы можете сделать это с помощью Y, вот как» по-прежнему является действительным ответом, поскольку вы не только отвечаете на вопрос OP, но также предоставляете альтернативу, которая будет работать. Это правильный ответ. – Thomas Ward♦ 11 May 2018 в 16:23
  • 4
    Спасибо @ThomasWard за это. – ubashu 12 May 2018 в 11:33

Это, в основном, решение Гленна, но реализовано с помощью Bash, Grep и sed.

grep -n match file |
    while IFS=: read nr _; do
        sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file
    done

Обратите внимание, что номера строк меньше 1 будут делать ошибку sed, а номера строк больше числа строк в файле будет ничего не печататься.

Это всего лишь минимальный минимум. Чтобы заставить его работать рекурсивно и обрабатывать указанные выше номера строк, потребуется некоторое время.

6
ответ дан 22 May 2018 в 10:49
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile

Здесь мы используем функцию system(command) awk для вызова внешней команды sed для печати строк, которые awk соответствует шаблону match с 5 строками до и после матча.

Синтаксис прост, вам просто нужно поместить внешнюю команду в двойную кавычку, а также ее ключи и избежать того, что вы хотите точно передать команде, все остальное, связанное с параметрами awk, должно быть вне кавычки. Итак, ниже awk :

"sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME

перевести на:

sed -n "NR-5p; NRp; NR+5p" FILENAME

NR - номер строки, который соответствует шаблону match и FILENAME - текущее имя файла обработки, проходящее через awk.

6
ответ дан 22 May 2018 в 10:49

с использованием текстового текстового файла @ glenn и использования perl вместо awk:

$ perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex

даст те же результаты, но работает быстрее:

a
f match
k
d
i match
n
2
ответ дан 22 May 2018 в 10:49
  • 1
    João, вы появляетесь в очереди просмотра LQ, а @waltinator проголосовали за удаление, поэтому в следующий раз крошечный бит будет более подробным ... ; -) Также + 1, чтобы вытащить вас из очереди LQ ... : P – Fabby 11 May 2018 в 16:48
  • 2
    @JJoao Низкая качество обзор очереди. Вероятно, ваш ответ был найден, потому что это был 90% -ый код. – wjandrea 11 May 2018 в 19:29
  • 3
    @JJoao 90% фигура - это всего лишь мой способ объяснить это. Я не знаю, какие эвристики фактически используются. – wjandrea 11 May 2018 в 21:41
  • 4
    Менос кафе, маис escrita! @JJoao : D ;-): D – Fabby 11 May 2018 в 21:51
  • 5
    @Fabby: Sem café nada funciona: D - возможно, он появится в LCQ (= низкая очередь кофе) – JJoao 12 May 2018 в 00:00

с использованием текстового текстового файла @ glenn и использования perl вместо awk:

$ perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex

даст те же результаты, но работает быстрее:

a f match k d i match n
2
ответ дан 17 July 2018 в 14:39

Это невозможно сделать только с помощью grep. Если параметр ed имеет значение:

ed -s file << 'EOF' g/match/-5p\ +5p\ +5p EOF

В сценарии в основном говорится: для каждого совпадения / match /, напечатайте линию 5 строк до этого, затем 5 строк после этого, затем 5 строк после что.

7
ответ дан 17 July 2018 в 14:39

Это, в основном, решение Гленна, но реализовано с помощью Bash, Grep и sed.

grep -n match file | while IFS=: read nr _; do sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file done

Обратите внимание, что номера строк меньше 1 будут делать ошибку sed, а номера строк больше числа строк в файле будет ничего не печататься.

Это всего лишь минимальный минимум. Чтобы заставить его работать рекурсивно и обрабатывать указанные выше номера строк, потребуется некоторое время.

6
ответ дан 17 July 2018 в 14:39
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile

Здесь мы используем функцию system(command) awk для вызова внешней команды sed для печати строк, которые awk соответствует шаблону match с 5 строками до и после матча.

Синтаксис прост, вам просто нужно поместить внешнюю команду в двойную кавычку, а также ее ключи и избежать того, что вы хотите точно передать команде, все остальное, связанное с параметрами awk, должно быть вне кавычки. Итак, ниже awk :

"sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME

перевести на:

sed -n "NR-5p; NRp; NR+5p" FILENAME

NR - номер строки, который соответствует шаблону match и FILENAME - текущее имя файла обработки, проходящее через awk.

6
ответ дан 17 July 2018 в 14:39

с использованием текстового файла примера @ glenn и использования perl вместо awk:

$ perl -n0E 'say /(.*\n)(?=(?:.*\n){4}(.*match.*\n)(?:.*\n){4}(.*\n))/g' ex

даст те же результаты, но работает быстрее:

a f match k d i match n
2
ответ дан 20 July 2018 в 14:42
  • 1
    João, вы появляетесь в очереди просмотра LQ, а @waltinator проголосовали за удаление, поэтому в следующий раз крошечный бит будет более подробным ... ; -) Также + 1, чтобы вытащить вас из очереди LQ ... : P – Fabby 11 May 2018 в 16:48
  • 2
    @JJoao Низкая качество обзор очереди. Вероятно, ваш ответ был найден, потому что это был 90% -ый код. – wjandrea 11 May 2018 в 19:29
  • 3
    @JJoao 90% фигура - это всего лишь мой способ объяснить это. Я не знаю, какие эвристики фактически используются. – wjandrea 11 May 2018 в 21:41
  • 4
    Менос кафе, маис escrita! @JJoao : D ;-): D – Fabby 11 May 2018 в 21:51
  • 5
    @Fabby: Sem café nada funciona: D - возможно, он появится в LCQ (= низкая очередь кофе) – JJoao 12 May 2018 в 00:00

Это невозможно сделать только с помощью grep. Если параметр ed имеет значение:

ed -s file << 'EOF' g/match/-5p\ +5p\ +5p EOF

В сценарии в основном говорится: для каждого совпадения / match /, напечатайте линию 5 строк до этого, затем 5 строк после этого, затем 5 строк после что.

7
ответ дан 20 July 2018 в 14:42
  • 1
    @ubashu Считаете ли вы, что это будет более полезно для OP, дающего простую квартиру, «это невозможно сделать с помощью grep»? Я предоставляю то, что считаю хорошей альтернативой решению проблемы OP. Из Справочного центра: «В чем конкретно заключается вопрос? Убедитесь, что ваш ответ предусматривает это - или жизнеспособную альтернативу. Ответ может быть «не делать этого», но он также должен включать «попробуйте это вместо». & Quot; – JoL 11 May 2018 в 03:16
  • 2
    ed является всегда ответом, потому что ed является стандартным текстовым редактором. – dessert 11 May 2018 в 11:28
  • 3
    @ubashu Хотя это не ответ grep, ответ «Вы не можете сделать это с X, но вы можете сделать это с помощью Y, вот как» по-прежнему является действительным ответом, поскольку вы не только отвечаете на вопрос OP, но также предоставляете альтернативу, которая будет работать. Это правильный ответ. – Thomas Ward♦ 11 May 2018 в 16:23

Это, в основном, решение Гленна, но реализовано с помощью Bash, Grep и sed.

grep -n match file | while IFS=: read nr _; do sed -ns "$((nr-5))p; $((nr))p; $((nr+5))p" file done

Обратите внимание, что номера строк меньше 1 будут делать ошибку sed, а номера строк больше числа строк в файле будет ничего не печататься.

Это всего лишь минимальный минимум. Чтобы заставить его работать рекурсивно и обрабатывать указанные выше номера строк, потребуется некоторое время.

6
ответ дан 20 July 2018 в 14:42
awk '/match/{system("sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME)}' infile

Здесь мы используем функцию system(command) awk для вызова внешней команды sed для печати строк, которые awk соответствует шаблону match с 5 строками до и после матча.

Синтаксис прост, вам просто нужно поместить внешнюю команду в двойную кавычку, а также ее ключи и избежать того, что вы хотите точно передать команде, все остальное, связанное с параметрами awk, должно быть вне кавычки. Итак, ниже awk :

"sed -n \"" NR-5 "p;" NR "p;" NR+5 "p\" " FILENAME

перевести на:

sed -n "NR-5p; NRp; NR+5p" FILENAME

NR - номер строки, который соответствует шаблону match и FILENAME - текущее имя файла обработки, проходящее через awk.

6
ответ дан 20 July 2018 в 14:42

Другие вопросы по тегам:

Похожие вопросы: