Расширенные команды sed и сопоставление шаблонов
Теперь, когда мы освоили базовые замены и редактирование файлов на месте с помощью sed, давайте рассмотрим некоторые более продвинутые функции:
- Использование различных разделителей
- Использование диапазонов адресов для обработки определенных строк
- Комбинирование нескольких команд
Использование различных разделителей
До сих пор мы использовали прямой слеш / в качестве разделителя в наших командах замены, но sed позволяет использовать любой символ в качестве разделителя. Это особенно полезно, когда шаблон или заменяемый текст содержат слеши.
Создадим файл с путями к файлам:
echo "/usr/local/bin is in the PATH" > ~/project/paths.txt
echo "My config is in /etc/myapp/config.json" >> ~/project/paths.txt
Если мы хотим заменить /usr/local/bin на /opt/bin, использование слешей может сбить с толку:
sed 's/\/usr\/local\/bin/\/opt\/bin/' ~/project/paths.txt
Вместо этого мы можем использовать другой разделитель, например #:
sed 's#/usr/local/bin#/opt/bin#' ~/project/paths.txt
Это гораздо более читаемо! Вывод должен быть таким:
/opt/bin is in the PATH
My config is in /etc/myapp/config.json
Другие распространенные разделители включают |, : и _.
Адресация - обработка определенных строк
sed позволяет нам указать, какие строки должны быть обработаны при замене. Это делается путем добавления адреса перед командой.
Создадим новый файл с пронумерованными строками:
echo "Line 1: This is the first line." > ~/project/numbered.txt
echo "Line 2: This is the second line." >> ~/project/numbered.txt
echo "Line 3: This is the third line." >> ~/project/numbered.txt
echo "Line 4: This is the fourth line." >> ~/project/numbered.txt
echo "Line 5: This is the fifth line." >> ~/project/numbered.txt
Чтобы заменить "line" на "row" только в третьей строке:
sed '3 s/line/row/' ~/project/numbered.txt
Вывод должен быть таким:
Line 1: This is the first line.
Line 2: This is the second line.
Line 3: This is the third row.
Line 4: This is the fourth line.
Line 5: This is the fifth line.
Мы также можем указать диапазон строк. Чтобы заменить "line" на "row" в строках от второй до четвертой:
sed '2,4 s/line/row/' ~/project/numbered.txt
Вывод должен быть таким:
Line 1: This is the first line.
Line 2: This is the second row.
Line 3: This is the third row.
Line 4: This is the fourth row.
Line 5: This is the fifth line.
Другой полезной функцией является возможность выбирать строки на основе шаблона. Например, чтобы заменить "line" на "row" только в строках, содержащих "third" или "fourth":
sed '/\(third\|fourth\)/ s/line/row/' ~/project/numbered.txt
Вывод должен быть таким:
Line 1: This is the first line.
Line 2: This is the second line.
Line 3: This is the third row.
Line 4: This is the fourth row.
Line 5: This is the fifth line.
Комбинирование нескольких команд
Мы можем комбинировать несколько команд sed с помощью опции -e или разделяя команды точкой с запятой.
Заменим "first" на "1st", "second" на "2nd" и "third" на "3rd" в одной команде:
sed -e 's/first/1st/' -e 's/second/2nd/' -e 's/third/3rd/' ~/project/numbered.txt
В качестве альтернативы мы можем использовать точки с запятой:
sed 's/first/1st/; s/second/2nd/; s/third/3rd/' ~/project/numbered.txt
Обе команды должны дать одинаковый вывод:
Line 1: This is the 1st line.
Line 2: This is the 2nd line.
Line 3: This is the 3rd line.
Line 4: This is the fourth line.
Line 5: This is the fifth line.
Теперь сделаем эти изменения постоянными:
sed -i 's/first/1st/; s/second/2nd/; s/third/3rd/' ~/project/numbered.txt
И проверим изменения:
cat ~/project/numbered.txt
Вы должны увидеть обновленный текст с порядковыми номерами.