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

2

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

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

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

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

Lokesh
источник
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
mikeserv
источник
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выше используется для объединения каждых двух строк, так что номер строки появляется непосредственно перед ее строкой.

John1024
источник
Спасибо за предоставление нескольких решений для моего вопроса.
Локеш
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