В этой главе мы подробно обсудим регулярные выражения с 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
Здесь command1 — commandN — команды 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 и т. Д. Мы использовали \, чтобы дать разрыв строки здесь. Это должно быть удалено перед запуском команды.