Учебники

Unix / Linux — регулярные выражения с SED

В этой главе мы подробно обсудим регулярные выражения с SED в Unix.

Регулярное выражение — это строка, которая может использоваться для описания нескольких последовательностей символов. Регулярные выражения используются несколькими различными командами Unix, включая ed , sed , awk , grep и, в более ограниченной степени, vi .

Здесь SED расшифровывается как s tream ed itor. Этот потоково-ориентированный редактор был создан исключительно для выполнения скриптов. Таким образом, все входные данные, которые вы вводите в него, проходят через STDOUT и не изменяют входной файл.

Вызывая сед

Прежде чем мы начнем, давайте удостоверимся, что у нас есть локальная копия текстового файла / etc / passwd для работы с sed .

Как упоминалось ранее, sed может быть вызван путем отправки данных через канал следующим образом:

$ cat /etc/passwd | sed
Usage: sed [OPTION]... {script-other-script} [input-file]...

  -n, --quiet, --silent
                 suppress automatic printing of pattern space
  -e script, --expression = script
...............................

Команда cat сбрасывает содержимое файла / etc / passwd для передачи через канал в пространство шаблонов sed. Пространство шаблона — это внутренний рабочий буфер, который sed использует для своих операций.

Общий синтаксис sed

Ниже приведен общий синтаксис для sed —

/pattern/action

Здесь pattern — это регулярное выражение, а action — одна из команд, приведенных в следующей таблице. Если шаблон не указан, действие выполняется для каждой строки, как мы видели выше.

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

Sr.No. Диапазон и описание
1

п

Печатает строку

2

d

Удаляет строку

3

с / pattern1 / шаблон2 /

Заменяет первое вхождение pattern1 на pattern2

п

Печатает строку

d

Удаляет строку

с / pattern1 / шаблон2 /

Заменяет первое вхождение pattern1 на pattern2

Удаление всех строк с помощью sed

Теперь мы поймем, как удалить все строки с помощью sed. Снова вызвать sed; но теперь предполагается, что sed использует строку удаления команды редактирования , обозначенную одной буквой d

$ cat /etc/passwd | sed 'd'
$

Вместо того, чтобы вызывать sed, посылая ему файл по каналу, sed можно поручить считывать данные из файла, как в следующем примере.

Следующая команда делает то же самое, что и в предыдущем примере, без команды cat —

$ sed -e 'd' /etc/passwd
$

Сед Адреса

Sed также поддерживает адреса. Адреса — это либо конкретные места в файле, либо диапазон, в котором должна применяться конкретная команда редактирования. Когда sed не встречает адресов, он выполняет свои операции над каждой строкой в ​​файле.

Следующая команда добавляет базовый адрес к используемой вами команде sed —

$ cat /etc/passwd | sed '1d' |more
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$

Обратите внимание, что число 1 добавляется перед командой удаления редактирования . Это дает команду sed выполнить команду редактирования в первой строке файла. В этом примере sed удалит первую строку / etc / password и напечатает остальную часть файла.

Адресные диапазоны sed

Теперь мы поймем, как работать с диапазонами адресов sed . Так что, если вы хотите удалить более одной строки из файла? Вы можете указать диапазон адресов с помощью sed следующим образом:

$ cat /etc/passwd | sed '1, 5d' |more
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
$

Вышеуказанная команда будет применена ко всем строкам, начиная с 1 по 5. Это удалит первые пять строк.

Попробуйте следующие диапазоны адресов —

Sr.No. Диапазон и описание
1

‘4,10d’

Строки с 4 по 10 удаляются

2

’10, 4d»

Удаляется только 10- я строка, потому что sed не работает в обратном направлении

3

‘4 + 5d’

Это соответствует строке 4 в файле, удаляет эту строку, продолжает удалять следующие пять строк, а затем прекращает ее удаление и печатает остальные

4

‘2,5! D’

Это удаляет все, кроме начиная со 2- й до 5- й строки

5

‘1 ~ 3d’

Это удаляет первую строку, переходит на следующие три строки, а затем удаляет четвертую строку. Сед продолжает применять этот шаблон до конца файла.

6

‘2 ~ 2d’

Это говорит sed, чтобы удалить вторую строку, перешагнуть через следующую строку, удалить следующую строку и повторять, пока не будет достигнут конец файла

7

‘4,10p’

Печатаются строки с 4 по 10

8

‘4, г’

Это генерирует синтаксическую ошибку

9

’10d’

Это также приведет к ошибке синтаксиса

‘4,10d’

Строки с 4 по 10 удаляются

’10, 4d»

Удаляется только 10- я строка, потому что sed не работает в обратном направлении

‘4 + 5d’

Это соответствует строке 4 в файле, удаляет эту строку, продолжает удалять следующие пять строк, а затем прекращает ее удаление и печатает остальные

‘2,5! D’

Это удаляет все, кроме начиная со 2- й до 5- й строки

‘1 ~ 3d’

Это удаляет первую строку, переходит на следующие три строки, а затем удаляет четвертую строку. Сед продолжает применять этот шаблон до конца файла.

‘2 ~ 2d’

Это говорит sed, чтобы удалить вторую строку, перешагнуть через следующую строку, удалить следующую строку и повторять, пока не будет достигнут конец файла

‘4,10p’

Печатаются строки с 4 по 10

‘4, г’

Это генерирует синтаксическую ошибку

’10d’

Это также приведет к ошибке синтаксиса

Примечание. При использовании действия p следует использовать параметр -n, чтобы избежать повторения печати строки. Проверьте разницу между следующими двумя командами:

$ cat /etc/passwd | sed -n '1,3p'
Check the above command without -n as follows −
$ cat /etc/passwd | sed '1,3p'

Команда замещения

Команда подстановки, обозначенная s , заменит любую указанную вами строку на любую другую указанную вами строку.

Чтобы заменить одну строку другой, sed должен иметь информацию о том, где заканчивается первая строка и начинается строка замещения. Для этого мы начнем с двух строк с символом косой черты ( / ).

Следующая команда заменяет первое вхождение в строке корня строки на строку amrood .

$ cat /etc/passwd | sed 's/root/amrood/'
amrood:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
..........................

Очень важно отметить, что sed заменяет только первое вхождение в строке. Если корень строки встречается в строке более одного раза, будет заменено только первое совпадение.

Чтобы sed выполнил глобальную подстановку, добавьте букву g в конец команды следующим образом:

$ cat /etc/passwd | sed 's/root/amrood/g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
...........................

Флаги замещения

Есть ряд других полезных флагов, которые могут быть переданы в дополнение к флагу g , и вы можете указать более одного за раз.

Sr.No. Флаг и описание
1

г

Заменяет все матчи, а не только первый

2

ЧИСЛО

Заменяет только NUMBER- й матч

3

п

Если подстановка была сделана, то печатается пробел

4

W FILENAME

Если подстановка была сделана, то записывает результат в FILENAME

5

Я или я

Совпадает без учета регистра

6

М или м

В дополнение к нормальному поведению специальных символов регулярного выражения ^ и $ этот флаг заставляет ^ соответствовать пустой строке после новой строки, а $ — пустой строке перед новой строкой

г

Заменяет все матчи, а не только первый

ЧИСЛО

Заменяет только NUMBER- й матч

п

Если подстановка была сделана, то печатается пробел

W FILENAME

Если подстановка была сделана, то записывает результат в FILENAME

Я или я

Совпадает без учета регистра

М или м

В дополнение к нормальному поведению специальных символов регулярного выражения ^ и $ этот флаг заставляет ^ соответствовать пустой строке после новой строки, а $ — пустой строке перед новой строкой

Использование альтернативного разделителя строк

Предположим, вам нужно выполнить подстановку строки, которая включает символ прямой косой черты. В этом случае вы можете указать другой разделитель, указав обозначенный символ после s .

$ cat /etc/passwd | sed 's:/root:/amrood:g'
amrood:x:0:0:amrood user:/amrood:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh

В приведенном выше примере мы использовали : в качестве разделителя вместо косой черты /, потому что мы пытались искать / корень вместо простого корня.

Замена на пустое пространство

Используйте пустую строку замещения, чтобы полностью удалить корневую строку из файла / etc / passwd

$ cat /etc/passwd | sed 's/root//g'
:x:0:0::/:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh

Замена адреса

Если вы хотите заменить строку sh строкой quiet только в строке 10, вы можете указать ее следующим образом:

$ cat /etc/passwd | sed '10s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/quiet

Аналогично, для замены диапазона адресов вы можете сделать что-то вроде следующего:

$ cat /etc/passwd | sed '1,5s/sh/quiet/g'
root:x:0:0:root user:/root:/bin/quiet
daemon:x:1:1:daemon:/usr/sbin:/bin/quiet
bin:x:2:2:bin:/bin:/bin/quiet
sys:x:3:3:sys:/dev:/bin/quiet
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

Как видно из выходных данных, в первых пяти строках строка sh была заменена на тихую , но остальные строки остались нетронутыми.

Соответствующая команда

Вы должны использовать опцию p вместе с опцией -n, чтобы напечатать все соответствующие строки следующим образом:

$ cat testing | sed -n '/root/p'
root:x:0:0:root user:/root:/bin/sh
[root@ip-72-167-112-17 amrood]# vi testing
root:x:0:0:root user:/root:/bin/sh
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

Использование регулярного выражения

При сопоставлении шаблонов вы можете использовать регулярное выражение, которое обеспечивает большую гибкость.

Проверьте следующий пример, который соответствует всем строкам, начинающимся с daemon, а затем удаляет их —

$ cat testing | sed '/^daemon/d'
root:x:0:0:root user:/root:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh

Ниже приведен пример, который удаляет все строки, заканчивающиеся на sh

$ cat testing | sed '/sh$/d'
sync:x:4:65534:sync:/bin:/bin/sync

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

Sr.No. Характер и описание
1

^

Соответствует началу строк

2

$

Соответствует концу строк

3

,

Соответствует любому отдельному символу

4

*

Соответствует нулю или более вхождений предыдущего символа

5

[символы]

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

^

Соответствует началу строк

$

Соответствует концу строк

,

Соответствует любому отдельному символу

*

Соответствует нулю или более вхождений предыдущего символа

[символы]

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

Соответствующие персонажи

Посмотрите еще несколько выражений, чтобы продемонстрировать использование метасимволов . Например, следующий шаблон —

Sr.No. Выражение и описание
1

/ AC /

Соответствует строкам, которые содержат строки, такие как & plus; c , ac , abc , match и a3c

2

/ а * с /

Сопоставляет одинаковые строки с такими строками, как ace , yacc и arctic

3

/ [Tt] он /

Соответствует строке

4

/ ^ $ /

Соответствует пустым строкам

5

/^.*$/

Соответствует всей строке, какой бы она ни была

6

/ * /

Соответствует одному или нескольким пробелам

7

/ ^ $ /

Соответствует пустым строкам

/ AC /

Соответствует строкам, которые содержат строки, такие как & plus; c , ac , abc , match и a3c

/ а * с /

Сопоставляет одинаковые строки с такими строками, как ace , yacc и arctic

/ [Tt] он /

Соответствует строке

/ ^ $ /

Соответствует пустым строкам

/^.*$/

Соответствует всей строке, какой бы она ни была

/ * /

Соответствует одному или нескольким пробелам

/ ^ $ /

Соответствует пустым строкам

Следующая таблица показывает некоторые часто используемые наборы символов —

Sr.No. Набор и описание
1

[AZ]

Соответствует одной строчной букве

2

[AZ]

Соответствует одной заглавной букве

3

[A-Za-Z]

Соответствует одной букве

4

[0-9]

Соответствует одному числу

5

[A-Za-Z0-9]

Соответствует одной букве или цифре

[AZ]

Соответствует одной строчной букве

[AZ]

Соответствует одной заглавной букве

[A-Za-Z]

Соответствует одной букве

[0-9]

Соответствует одному числу

[A-Za-Z0-9]

Соответствует одной букве или цифре

Ключевые слова класса символов

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

Например, символы от a до z и символы от A до Z составляют один такой класс символов, который имеет ключевое слово [[: alpha:]]

Используя ключевое слово класса символов алфавита, эта команда печатает только те строки в файле /etc/syslog.conf, которые начинаются с буквы алфавита —

$ cat /etc/syslog.conf | sed -n '/^[[:alpha:]]/p'
authpriv.*                         /var/log/secure
mail.*                             -/var/log/maillog
cron.*                             /var/log/cron
uucp,news.crit                     /var/log/spooler
local7.*                           /var/log/boot.log

В следующей таблице приведен полный список доступных ключевых слов класса символов в GNU sed.

Sr.No. Класс персонажа и описание
1

[[цифра , буква]]

Буквенно-цифровой [аз AZ 0-9]

2

[[:альфа:]]

Алфавитный [az AZ]

3

[[: пусто:]]

Пустые символы (пробелы или символы табуляции)

4

[[: CNTRL:]]

Управляющие персонажи

5

[[: цифры:]]

Числа [0-9]

6

[[: график:]]

Любые видимые символы (исключая пробелы)

7

[[: ниже:]]

Строчные буквы [az]

8

[[:Распечатать:]]

Печатные символы (неуправляемые символы)

9

[[пунктуатор]]

Знаки пунктуации

10

[[:пространство:]]

Пробелы

11

[[: верхняя:]]

Прописные буквы [AZ]

12

[[: xdigit:]]

Шестнадцатеричные цифры [0-9 af AF]

[[цифра , буква]]

Буквенно-цифровой [аз AZ 0-9]

[[:альфа:]]

Алфавитный [az AZ]

[[: пусто:]]

Пустые символы (пробелы или символы табуляции)

[[: CNTRL:]]

Управляющие персонажи

[[: цифры:]]

Числа [0-9]

[[: график:]]

Любые видимые символы (исключая пробелы)

[[: ниже:]]

Строчные буквы [az]

[[:Распечатать:]]

Печатные символы (неуправляемые символы)

[[пунктуатор]]

Знаки пунктуации

[[:пространство:]]

Пробелы

[[: верхняя:]]

Прописные буквы [AZ]

[[: xdigit:]]

Шестнадцатеричные цифры [0-9 af AF]

Aampersand Referencing

Метасимвол sed & представляет содержимое сопоставленного шаблона. Например, скажем, у вас есть файл phone.txt, полный телефонных номеров, например, такой:

5555551212
5555551213
5555551214
6665551215
6665551216
7775551217

Вы хотите сделать код города (первые три цифры) в круглых скобках для удобства чтения. Для этого вы можете использовать символ замены амперсанда —

$ sed -e 's/^[[:digit:]][[:digit:]][[:digit:]]/(&)/g' phone.txt
(555)5551212
(555)5551213
(555)5551214
(666)5551215

(666)5551216
(777)5551217

Здесь в части шаблона вы сопоставляете первые 3 цифры, а затем используете & вы заменяете эти 3 цифры на окружающие скобки .

Использование нескольких команд sed

Вы можете использовать несколько команд sed в одной команде sed следующим образом:

$ sed -e 'command1' -e 'command2' ... -e 'commandN' files

Здесь command1commandN — команды sed типа, обсужденного ранее. Эти команды применяются к каждой из строк в списке файлов, заданных файлами.

Используя тот же механизм, мы можем написать приведенный выше пример номера телефона следующим образом:

$ sed -e 's/^[[:digit:]]\{3\}/(&)/g'  \ 
   -e 's/)[[:digit:]]\{3\}/&-/g' phone.txt 
(555)555-1212 
(555)555-1213 
(555)555-1214 
(666)555-1215 
(666)555-1216 
(777)555-1217

Примечание. В приведенном выше примере вместо трехкратного повторения ключевого слова класса символов [[: digit:]] мы заменили его на \ {3 \} , что означает, что предыдущее регулярное выражение сопоставляется три раза. Мы также использовали \ для разрыва строки, и это нужно удалить до запуска команды.

Вернуться Отзывы

Метасимвол амперсанда полезен, но еще более полезна возможность определять определенные области в регулярных выражениях. Эти специальные области могут быть использованы в качестве ссылки в строках замены. Определив определенные части регулярного выражения, вы можете затем обратиться к этим частям со специальным ссылочным символом.

Чтобы сделать обратные ссылки , вы должны сначала определить регион, а затем вернуться к этому региону. Чтобы определить регион, вы вставляете круглые скобки с обратной косой чертой вокруг каждой интересующей области. На первый регион, который вы окружаете обратными слешами, ссылается \ 1 , на второй регион — \ 2 и так далее.

Предполагая, что phone.txt имеет следующий текст —

(555)555-1212
(555)555-1213
(555)555-1214
(666)555-1215
(666)555-1216
(777)555-1217

Попробуйте следующую команду —

$ cat phone.txt | sed 's/\(.*)\)\(.*-\)\(.*$\)/Area \ 
   code: \1 Second: \2 Third: \3/' 
Area code: (555) Second: 555- Third: 1212 
Area code: (555) Second: 555- Third: 1213 
Area code: (555) Second: 555- Third: 1214 
Area code: (666) Second: 555- Third: 1215 
Area code: (666) Second: 555- Third: 1216 
Area code: (777) Second: 555- Third: 1217

Примечание. В приведенном выше примере каждое регулярное выражение в скобках будет иметь обратную ссылку \ 1 , \ 2 и т. Д. Мы использовали \, чтобы дать разрыв строки здесь. Это должно быть удалено перед запуском команды.