Поиск по шаблону между конкретными строками и номерами строк печати


2

У меня есть файл из 20 строк. Я хочу найти строку между строками 10 и 15 и распечатать строку вместе с номерами строк исходного файла.

я пытался sed -n 10,15p file | grep -n "pattern"

Проблема с вышеприведенной командой состоит в том, что строка вывода с номером 10 sedбудет строкой с номером 1 для grep.

Следовательно, он не печатает номера строк из исходного файла.


sed '10,15!d;/pattern/!d;='
mikeserv

Спасибо за быстрый ответ Mikeserv, все заработало как положено.
Локеш

Ответы:


3

Когда я работаю с sedженой, мне легче всего сузить круг возможных результатов. Вот почему я иногда опираюсь на !оператор отрицания. Очень часто проще отсеять неинтересный вклад, чем демонстративно выбрать интересный вид - по крайней мере, это мое мнение по этому вопросу.

Я нахожу этот метод более встроенным в sedповедение по умолчанию, которое заключается в автоматической печати пространства шаблонов в конце сценария. Для простых вещей, таких как это, это также может легко привести к созданию надежного сценария - сценария, который не зависит от синтаксических расширений определенных реализаций для работы (как это обычно наблюдается sed {functions}) .

Вот почему я рекомендовал вам сделать:

sed '10,15!d;/pattern/!d;=' <input

... которая сначала обрезает любую линию, находящуюся вне диапазона строк 10 и 15, и из числа тех, которые остаются, обрезает любую линию, которая не соответствует pattern. Если вы обнаружите, что предпочли бы, чтобы номер строки sedпечатался на той же строке, что и совпадающая строка, я бы, вероятно, посмотрел pasteв этом случае. Может быть...

sed '10,15!d;/pattern/!d;=' <input |
paste -sd:\\n -

... который будет чередовать замену входных электронных \nлиний :символом или другой электронной \nстрокой.

Например:

seq 150 |
sed '10,50!d;/5/!d;=' |
paste -sd:\\n -

... печать ...

15:15
25:25
35:35
45:45
50:50

1

Вот awkрешение:

awk '10<=NR && NR<=15 && /pattern/ {print NR,$0}' file

Если мы должны использовать только sed , то подумайте:

sed -n '10,15 {/pattern/ {=;p}}' file | sed 'N;s/\n/ /'

=Команда sed будет печатать только номер строки в отдельной строке. Второй пример sedвыше используется для объединения каждых двух строк, так что номер строки появляется непосредственно перед ее строкой.


Спасибо за предоставление нескольких решений для моего вопроса.
Локеш

1

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

nl file | sed -n '10,15{/pattern/p
}'

1
В качестве альтернативы nlвы можете использовать cat -nдля получения нумерации строк, но эта опция доступна не во всех версиях cat; Я предполагаю, что это расширение GNU.
PM 2Ring

1
@ PM2Ring, тогда nlкак POSIX.
Муру

1
@muru - да, это POSIX, но sedэто не так. Вам нужен \newline перед любым }. В большинстве случаев ...' -e \}будет делать вместо. Единственный случай, который я обнаружил, в котором я не могу полагаться на это, - это электронная \nлиния в правой части s///тела. Я задал вопрос об этом однажды , но кроме полезных советов, я узнал, как справиться с этим с помощью проб и ошибок.
mikeserv
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.