sed -s substitute

Содержание
Введение
Замена слова в файле
Замена слова в нескольких файлах одновременно
Замена только в определённых строках
g
Добавить отступы
Заменить пустые строки
Изменить начало строки
Изменить значение в JSON
Работа с пробелами в путях Windows
Статьи про SED

Введение

Чтобы использовать команду sed substitute нужна опция 's'

Общий синтаксис выглядит так:

sed '[range] s/<string>/<replacement>/' file

Перевод

sed ' [диапазон] s/<строка>/<замена>/' файл

range - это область в которой нужно делать замену. Задаётся через условие. Всегда должен быть внутри / /

string - это набор символов который нужно заменить

replacement - это набор символов на который заменяется string

file - это имя файла (можно с путём до файла) в котором эта замена будет произведена

Замена слова в файле

Обычно SED применяют к файлам, например к логам или конфигам.

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String Here is an Integer Here is a Float

Мы хотим заменить слово Here на There

sed 's/Here/There/' input.txt

Результат будет выведен в консоль:

There is a String

There is an Integer

There is a Float

Если нужно не вывести в консоль (в stdout) а изменить содержание файла - используем опцию -i

sed -i 's/Here/There/' input.txt

В этом случае перепишется исходный файл input.txt

Хорошей практикой считается сначала проверить свой скрипт без -i и если всё работает верно внести изменения в файл.

С помощью -i.bak можно создать резервный файл (бэкап)

Рассмотрим пример посложнее.

Пусть файл input.txt теперь выглядит так:

Here is an Apple. Here is a Pen. Here is an ApplePen Integer is Here Here is a Float Here is a Pen. Here is a Pineapple. Here is a PineapplePen

sed 's/Here/There/' input.txt

Как Вы сейчас увидите, замена произойдёт только по одному разу в строке

There is an Apple. Here is a Pen. Here is an ApplePen

Integer is There

There is a Float

There is a Pen. Here is a Pineapple. Here is a PineapplePen

Чтобы заменить все слова нужна опция g

sed 's/Here/There/g' input.txt

There is an Apple. There is a Pen. There is an ApplePen
Integer is There

There is a Float

There is a Pen. There is a Pineapple. There is a PineapplePen

ApplePen

Замена слова в файле и вывод результата в другой файл

Та же замена, но с выводом в новый текстовый файл, который мы назовём output:

sed 's/Here/There/' input.txt > output.txt

Замена слова в нескольких файлах одновременно

Если нужно обработать сразу несколько файлов: например файл 1.txt с содержанием

First File: Here

И файл 2.txt с содержанием

Second File: Here

Это можно сделать используя *.txt

sed 's/Here/There/' *.txt > output.txt

На выходе файл output.txt будет выглядеть так

First File: There Second File: There

Замена только в определённых строках

Рассмотрим файл input.txt

cat input.txt

lex red red test red muha lex red red lex red lex blue

Заменим red на yellow, но не везде, а только там где строка начинается с lex

sed -i '/^lex/ s/red/yellow/' input.txt

cat input.txt

lex yellow red test red muha lex red red lex yellow lex blue

/^lex/ - замену нужно делать только в тех строках, которые начинаются с lex - так мы задали range

g

Если не задавать range как в предыдущем примере ,то в каждой строке первый red будет заменён на yellow

sed -i 's/red/yellow/' input.txt

cat input.txt

lex yellow yellow test yellow muha lex yellow red lex yellow lex blue

Чтобы заменить вообще все red на yellow - нужно добавить опцию g (greed - жадность)

sed -i 's/red/yellow/g' input.txt

cat input.txt

lex yellow yellow test yellow muha lex yellow yellow lex yellow lex blue

Добавить отступы

Рассмотрим скрипт script.sh

nl -ba script.sh

1 #!/bin/bash 2 3 i=0 4 while [ $i -le 3 ] 5 do 6 echo "i= " 7 echo $i 8 (( i++ )) 9 done

Если вы решите добавить отступы внутри dodone : то есть отодвинуть, скажем, на четыре пробела текст в строках 6, 7 и 8 - выполните

sed -i ' 6,8 s/^/    /g' script.sh

nl -ba script.sh

1 #!/bin/bash 2 3 i=0 4 while [ $i -le 3 ] 5 do 6 echo "i= " 7 echo $i 8 (( i++ )) 9 done

Предупреждаю, что если у вас в скрипте есть пустые строки - nl их считать не будет а sed будет - поэтому я использовал nl с опциями ba

Если вносить изменения в исходный файл не нужно - можно использовать

sed -n ' 6,8 s/^/    /p' script.sh

echo "i= " echo $i (( i++ ))

Заменить пустые строки

Заменить все пустые строки на двойные тэги переноса строки

$ sed 's/^[[:space:]]*$/\<br\>\<br\>/' input.txt > output.txt

Заменить начало строки

Рассмотрим файл input.txt

cat input.txt

lex red red test red muha lex red red lex red lex blue

На начало строки указывает символ ^

Заменим red на yellow, но не везде, а только там где строка начинается с lex

sed -i '/^lex/ s/red/yellow/' input.txt

cat input.txt

lex yellow red test red muha lex red red lex yellow lex blue

Изменить значение в JSON файле

Рассмотрим файл sample.json в котором SpamBlocking нужно заменить на true по умолчанию

{ "websites": { "AppUpdateURL": "", "BlockAddons": true, "EncryptedExtensions": { "Enabled": true, "Locked": true }, "SpamBlocking": { "Default": false }, "Permissions": { "Camera": { "BlockRequests": true }, "Location": { "BlockRequests": true }, "Microphone": { "BlockRequests": true }, "Popups": { "BlockRequests": true } } } }

Если значение SpamBlocking встречается в JSON файле только один раз - подойдёт следующий скрипт j.sh

# www.andreyolegovich.ru FILENAME=sample.json PATTERN=SpamBlocking # Find line number of the PATTERN PREVLINE=$(sed -n /$PATTERN/= ./$FILENAME) # Calculate line with value LINE=$(( $PREVLINE + 1 )) # Replace sed -i $LINE's@false@true@' ./$FILENAME

./j.sh

Проверить результать можно с помощью grep

grep -A1 SpamBlocking sample.json

"SpamBlocking": { "Default": true

Работа с пробелами в путях Windows

Если нужно применить sed в Windows нужно учесть возможное наличие пробелов в путях.

Предположим настройки софта лежат в файлах Studio.exe.config , Loader.exe.config Tool.exe.config в директории

C:\Program Files\My Win Software

Или если открыть через Git Bash

/c/Program Files/My Win Software

и её поддиректории net48. Строка, в которой прописан уровень логов, содержит <variable name="logLevel"

Цель - заменить уровень логов с Erorr на Debug

WD=/c/Program\ Files/My\ Win\ Software S="$WD/Studio.exe.config" L="$WD/Loader.exe.config" T="$WD/net48/Tool.exe.config" /usr/bin/sed.exe -i '/<variable name="logLevel"/ s/Error/Debug/' "$S" "$L" "$T"

Похожие статьи
SED
find + sed
p: sed print
s: sed substitute
a i d: append insert delete
Несколько команд одновременно
-e: --expression=script
d: Удаление
sed через ssh
find + sed
Групповая замена
sed в vim
Linux
Bash
Bash Scripting
AWK
GREP