Компиляция из двух смежных статей на тему использования команды sed
для редактирования текстовых файлов, включая различные варианты поиска и замены шаблонов, а также всевозможные операции со строками. Идею к публикации этого гайда подал участник nronnie в комментарии к предыдущей статье, посвящённой работе с Bash.
SED – это потоковый редактор текста (от stream editor), c помощью которого можно выполнять с файлами множество операций вроде поиска и замены, вставки или удаления. При этом чаще всего он используется именно для поиска и замены.
SED позволяет редактировать файлы, не открывая, что существенно ускоряет работу, чем при использовании того же vi. Помимо этого, SED поддерживает регулярные выражения, с помощью которых можно выполнять сложное сопоставление шаблонов.
Общий синтаксис команды sed
выглядит так:
sed OPTIONS... [SCRIPT] [INPUTFILE...]
Сами же варианты её использования мы рассмотрим на примере следующего отрывка текста:
$cat > geekfile.txt
unix is great os. unix is opensource. unix is free os.
learn operating system.
unix linux which one you choose.
unix is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
Примеры команд
1. Замена заданного шаблона
Следующая команда заменит в целевом файле вхождения слова unix
на linux
:
$sed 's/unix/linux/' geekfile.txt
Вывод:
linux is great os. unix is opensource. unix is free os.
learn operating system.
linux linux which one you choose.
linux is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
Здесь s
обозначает операцию замены, а прямые слэши выступают разделителями. В качестве искомого шаблона используется unix
, а в качестве его замены linux
.
По умолчанию команда sed
заменяет первое вхождение шаблона в каждой строке, не затрагивая второе, третье и т.д.
2. Замена n-ого вхождения шаблона в строке
Вхождения, которые нужно заменить, обозначаются с помощью флагов /1
, /2
и т.д. К примеру, следующая команда заменит в каждой строке второе вхождение:
$sed 's/unix/linux/2' geekfile.txt
Вывод:
unix is great os. linux is opensource. unix is free os.
learn operating system.
unix linux which one you choose.
unix is easy to learn.linux is a multiuser os.Learn unix .unix is a powerful.
3. Замена всех вхождений шаблона в файле
Дя замены всех без исключения вхождений заданного шаблона используется глобальный флаг /g
:
$sed 's/unix/linux/g' geekfile.txt
Вывод:
linux is great os. linux is opensource. linux is free os.
learn operating system.
linux linux which one you choose.
linux is easy to learn.linux is a multiuser os.Learn linux .linux is a powerful.
4. Замена всех вхождений шаблона в строке начиная с n-ого
Для этого номер вхождения, с которого нужно начать, сопровождается флагом g
. Следующая команда заменит в каждой строке третье, четвёртое и т.д. вхождения слова unix
на слово linux
:
$sed 's/unix/linux/3g' geekfile.txt
Вывод:
unix is great os. unix is opensource. linux is free os.
learn operating system.
unix linux which one you choose.
unix is easy to learn.unix is a multiuser os.Learn linux .linux is a powerful.
5. Заключение первых символов слов в скобки
Следующая команда заключит в скобки первый символ каждого слова:
$ echo "Welcome To The Geek Stuff" | sed 's/(b[A-Z])/(1)/g'
Вывод:
(W)elcome (T)o (T)he (G)eek (S)tuff
6. Замена шаблона в конкретной строке
Можно ограничить выполнение команды sed
нужной строкой:
$sed '3 s/unix/linux/' geekfile.txt
Вывод:
unix is great os. unix is opensource. unix is free os.
learn operating system.
linux linux which one you choose.
unix is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
Вышеприведённая команда заменяет заданное слово только в третьей строке.
7. Дублирование изменяемых строк
При добавлении флага /p
команда выведет в терминал строки, где производится замена. Строки, в которых искомый шаблон отсутствует, не дублируются.
$sed 's/unix/linux/p' geekfile.txt
Вывод:
linux is great os. unix is opensource. unix is free os.
linux is great os. unix is opensource. unix is free os.
learn operating system.
linux linux which one you choose.
linux linux which one you choose.
linux is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
linux is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
8. Вывод только строк с заменой
Если рядом с флагом /p
добавить ключ -n
, в терминале отобразятся только строки, где выполнялась замена. В данном случае -n
отключает дублирующее поведение флага /p
, поэтому строки с заменой выводятся по одному разу.
$sed -n 's/unix/linux/p' geekfile.txt
Вывод:
linux is great os. unix is opensource. unix is free os.
linux linux which one you choose.
linux is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
Если использовать только -n
, исключив /p
, вывод команда не произведёт.
9. Замена шаблона в указанном диапазоне строк
sed
позволяет указывать диапазон строк, в которых требуется заменить определённый шаблон:
$sed '1,3 s/unix/linux/' geekfile.txt
Вывод:
linux is great os. unix is opensource. unix is free os.
learn operating system.
linux linux which one you choose.
unix is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful.
Здесь sed
производит замену в строках с 1 по 3. А вот ещё один пример:
$sed '2,$ s/unix/linux/' geekfile.txt
Вывод:
unix is great os. unix is opensource. unix is free os.
learn operating system.
linux linux which one you choose.
linux is easy to learn.unix is a multiuser os.Learn unix .unix is a powerful
Здесь $
указывает на последнюю строку файла, в связи с чем sed
заменяет первые вхождения шаблона, начиная со второй и заканчивая ей.
10. Удаление строк из файла
С помощью sed
также можно удалять строки из заданного файла:
10.1 Удаление n-ой строки:
Синтаксис: $ sed 'nd' filename.txt
Пример: $ sed '5d' filename.txt
10.2 Удаление последней строки:
Синтаксис: $ sed '$d' filename.txt
10.3 Удаление строк с x> по y:
Синтаксис: $ sed 'x,yd' filename.txt
Пример: $ sed '3,6d' filename.txt
10.4 Удаление строк с n-ой до последней:
Синтаксис: $ sed 'n,$d' filename.txt
Пример: $ sed '12,$d' filename.txt
10.5 Удаление текста, соответствующего шаблону:
Синтаксис: $ sed '/pattern/d' filename.txt
Пример: $ sed '/abc/d' filename.txt
Примеры команд (продолжение)
Во второй части мы разберём ещё одну серию операций с командой sed
на примере уже другого файла, a.txt. Чтобы излишне не растягивать статью, вывод команд далее приводится не будет, так что для лучшего понимания можете самостоятельно попрактиковаться, создав такой же файл с аналогичным содержимым.
[root@rhel7 ~]# cat a.txt
life isn't meant to be easy, life is meant to be lived.
Try to learn & understand something new everyday in life.
Respect everyone & most important love everyone.
Don’t hesitate to ask for love & don’t hesitate to show love too.
Life is too short to be shy.
In life, experience will help you differentiating right from wrong.
Добавление/удаление пустых строк в файле
1. Вставить после каждой текстовой строки одну пустую:
[root@rhel7 ~]# sed G a.txt
2. Вставить две пустые строки:
[root@rhel7 ~]# sed 'G;G' a.txt
3. Удалить все пустые строки и вставить по одной после каждой текстовой:
[root@rhel7 ~]# sed '/^$/d;G' a.txt
4. Вставить пустую строку над каждой, содержащей love
:
[root@rhel7 ~]# sed '/love/{x;p;x;}' a.txt
5. Вставить пустую строку после каждой, содержащей love
:
[root@rhel7 ~]# sed '/love/G' a.txt
6. Вставить 5 пробелов слева от каждой строки:
[root@rhel7 ~]# sed 's/^/ /' a.txt
Нумерация строк
1. Пронумеровать каждую строку файла (с левым выравниванием).
В этой команде символ =
используется для нумерации строки, а флаг t
для табулирования между номером и предложением:
Пример: [root@rhel7 ~]# sed = a.txt | sed 'N;s/n/t/'
2. Пронумеровать каждую строку файла (число слева, выравнивание по правому краю).
Эта команда похожа на `cat -n filename`
:
Пример: [root@rhel7 ~]# sed = a.txt | sed 'N; s/^/ /; s/ *(.{4,})n/1 /'
3. Пронумеровать каждую непустую строку файла:
Пример: [root@rhel7 ~]# sed '/./=' a.txt | sed '/./N; s/n/ /'
Удаление строк
1. Удалить конкретную строку:
Синтаксис: sed ‘nd’ filename
Пример: [root@rhel7 ~]# sed '5d' a.txt
2. Удалить последнюю строку:
Синтаксис: sed ‘$d’ filename
3. Удалить строки с x
по y
:
Синтаксис: sed ‘x,yd’ filename
Пример: [root@rhel7 ~]# sed '3,5d' a.txt
4. Удалить строки с n-ой до последней:
Синтаксис: sed ‘n,$d’ filename
Пример: [root@rhel7 ~]# sed '2,$d' a.txt
5. Удалить строку, содержащую шаблон:
Синтаксис: sed ‘/pattern/d’ filename
Пример: [root@rhel7 ~]# sed '/life/d' a.txt
6. Удалить каждую вторую строку начиная с n-ой:
Синтаксис: sed ‘n~2d’ filename
Пример: [root@rhel7 ~]# sed '3~2d' a.txt
7. Удалить строки, содержащие шаблон, и по две строки после них:
Синтаксис: sed ‘/pattern/,+2d’ filename
Пример: [root@rhel7 ~]# sed '/easy/,+2d' a.txt
8. Удалить пустые строки:
Пример: [root@rhel7 ~]# sed '/^$/d' a.txt
9. Удалить пустые строки или начинающиеся с #
:
Пример: [root@rhel7 ~]# sed -i '/^#/d;/^$/d' a.txt
Просмотр/вывод строк
Для просмотра содержимого файла мы используем команду cat
, а его начало и конец просматриваем с помощью утилит head
и tail
. Но что, если нас интересует некий участок в середине файла? В таком случае можно снова задействовать sed
.
1. Просмотреть файл со строки x по y:
Синтаксис: sed -n ‘x,yp’ filename
Пример: [root@rhel7 ~]# sed -n '2,5p' a.txt
2. Просмотреть весь файл, за исключением заданного диапазона:
Синтаксис: sed ‘x,yd’ filename
Пример: [root@rhel7 ~]# sed '2,4d' a.txt
3. Вывести n-ую строку файла:
Синтаксис: sed -n ‘address’p filename
Пример: [root@rhel7 ~]# sed -n '4'p a.txt
4. Вывести строки с x по y:
Синтаксис: sed -n ‘x,y’p filename
Пример: [root@rhel7 ~]# sed -n '4,6'p a.txt
5. Вывести только последнюю строку:
Синтаксис: sed -n ‘$’p filename
6. Вывести с n-ой строки до последней:
Синтаксис: sed -n ‘n,$p’ filename
Пример: [root@rhel7 ~]# sed -n '3,$'p a.txt
7. Вывести строки, содержащие указанный шаблон:
Синтаксис: sed -n /pattern/p filename
Пример: [root@rhel7 ~]# sed -n /every/p a.txt
8. Вывести строки начиная с первой, где обнаружен шаблон, и до строки x:
Синтаксис: sed -n ‘/pattern/,xp’ filename
Пример: [root@rhel7 ~]# sed -n '/everyone/,5p' a.txt
В данном случае первое вхождение everyone
содержится в строке 3, значит в терминале отобразятся строки с 3 по 5. Если нужно вывести файл до конца, используйте вместо 5 символ $
.
9. Вывести строки с x и до строки, содержащей шаблон. Если шаблон не обнаруживается, выводится файл до конца:
Синтаксис: sed -n ‘x,/pattern/p’ filename
Пример: sed -n '1,/everyone/p' a.txt
10. Вывести все строки, содержащие шаблон, включая следующие за каждой из них x строк:
Синтаксис: sed -n ‘/pattern/,+xp’ filename
Пример: sed -n '/learn/,+2p' a.txt
Замена с помощью команды sed (дополнение)
Ниже приводится небольшой список операций, дополняющий перечисленные ранее.
1. Два способа замены шаблона, игнорируя регистр:
1.1 Использовать флаг /i
:
Синтаксис: sed ‘s/old_pattern/new_pattern/i’ filename
Пример: [root@rhel7 ~]# sed 's/life/Love/i' a.txt
1.2 Использовать регулярные выражения:
Пример: [root@rhel7 ~]# sed 's/[Ll]ife/Love/g' a.txt
2. Замена нескольких пробелов одним:
Пример: [root@rhel7 clang]# sed ‘s/ */ /g’ filename
3. Замена шаблона, сопровождающего другой шаблон:
Синтаксис: sed ‘/followed_pattern/ s/old_pattern/new_pattern/’ filename
Пример: [root@rhel7 ~]# sed '/is/ s/live/love/' a.txt
10. Замена шаблона другим шаблоном, за исключением строки n:
Синтаксис: sed ‘n!s/old_pattern/new_pattern/’ filename
Пример: [root@rhel7 ~]# sed -i '5!s/life/love/' a.txt
В Linux команда tr
используется для выполнения различных преобразований текста: преобразования регистра, сжатия и удаления символов, базовой замены текста.
В связи с тем, что утилита может читать файл напрямую и выводить результаты в стандартный вывод, она часто используется с конвейерами и перенаправлениями для обеспечения более сложной обработки содержимого файла.
Содержание
- Синтаксис
- Опции
- Использование команды tr в Linux
- Запуск без параметров
- Изменение регистра символов
- Удаление повторяющихся символов
- Удаление определённых символов
- Дополнения
- Удаление символов новой строки
- Сохранение вывода в файл
- Вывод списка уникальных слов
- Заключение
Синтаксис
tr [Опции] МАССИВ1 [МАССИВ2]
Опции
- -c, -C, –complementuse
- Используйте дополнение МАССИВ1
- -d, –delete
- Удалить символы в МАССИВЕ1, не переводить
- -s, –squeeze-repeats
- Замените каждую последовательность повторяющихся символов, перечисленных в последнем указанном МАССИВЕ, одним вхождением этого символа
- -t, –truncate-set1
- Сначала усеките МАССИВ1 до длины МАССИВ2
МАССИВЫ указываются как строки символов.
Интерпретируемые последовательности:
- NNN
- Символы с NNNвосьмеричным значением NNN (от 1 до 3 восьмеричных цифр)
- \
- Обратный слэш
- a
- Звуковой сигнал
- b
- Клавиша Backspace
- f
- Подача формы
- n
- Новая строка
- r
- Возврат каретки
- t
- Горизонтальная табуляция
- v
- Вертикальная табуляция
- [:alnum:]
- Все буквы и цифры
- [:alpha:]
- Все буквы
- [:blank:]
- Все горизонтальные пробелы
- [:cntrl:]
- Все управляющие символы
- [:digit:]
- Все цифры
- [:graph:]
- Все печатные символы, исключая пробел
- [:lower:]
- Все строчные буквы
- [:print:]
- Все печатные символы, включая пробел
- [:punct:]
- Все знаки пунктуации
- [:space:]
- Все горизонтальные или вертикальные пробельные символы
- [:upper:]
- Все заглавные буквы
- [:xdigit:]
- Все шестнадцатеричные числа
Преобразование происходит, если -d
не задано и появляются как МАССИВ1, так и МАССИВ2. -t
можно использовать только при переводе. МАССИВ2 расширяется до длины МАССИВА1 за счёт повторения его последнего символа по мере необходимости.
Лишние символы МАССИВА2 игнорируются.
Классы символов расширяются в неопределенном порядке; при переводе [:lower:]
и [:upper:]
могут использоваться парами для указания преобразования регистра.
Сжатие происходит после перевода или удаления.
Использование команды tr в Linux
Запуск без параметров
Запуск команды без каких-либо параметров заменяет каждый из символов, указанных в МАССИВЕ1, на символы из МАССИВА2 того же положения.
oleg@mobile:~:$ echo "Hellu, Wurld!" | tr u o
Hello, World!
oleg@mobile:~:$
Были исправлены ошибки в тексте, произведена замена u
на o
.
Изменение регистра символов
Существует три способа изменения регистра символов:
- указание точных символов для преобразования;
- указание диапазона символов для преобразования;
- указание интерпретируемых последовательностей.
Указание точных символов для преобразования
Преобразование одного символа:
oleg@mobile:~:$ tr м М
массив
Массив
Преобразование нескольких символов:
oleg@mobile:~:$ tr м,а,с,и,в М,А,С,И,В
массив
МАССИВ
Указание диапазона символов для преобразования
В указанном диапазоне можно изменить регистр любого символа, например преобразовать нижний регистр в верхний:
oleg@mobile:~:$ tr a-z A-Z
hello, guys!
HELLO, GUYS!
Преобразует лишь символы латиницы.
Указание интерпретируемых последовательностей
Пример аналогичен предыдущему, но указывается не диапазон, а последовательности:
oleg@mobile:~:$ tr [:lower:] [:upper:]
hello, guys!
HELLO, GUYS!
Также, как и предыдущий способ преобразует лишь символы латиницы.
Удаление повторяющихся символов
Опция -s
позволяет сжимать повторяющиеся символы в один. Это очень полезно, например при наличии в тексте ряда пробелов, следующих один за другим:
oleg@mobile:~:$ echo "Добро пожаловать к нам на рюмку чая!" | tr -s [:space:]
Добро пожаловать к нам на рюмку чая!
oleg@mobile:~:$
Удаление определённых символов
В этом случае используется опция -d
:
oleg@mobile:~:$ echo "That's rok. Thanks a lort" | tr -d 'r'
That's ok. Thanks a lot
oleg@mobile:~:$
Удаление группы символов, например все цифры, указав [:digit:]
последовательность:
oleg@mobile:~:$ echo "Ваш пин-код: 2022" | tr -d [:digit:]
Ваш пин-код:
oleg@mobile:~:$
Дополнения
Если к предыдущему примеру добавить опцию -c
, то будут удалены все символы, кроме цифр:
oleg@mobile:~:$ echo "Ваш пин-код: 2022" | tr -cd [:digit:]
2022oleg@mobile:~:$
Удаление символов новой строки
Порой возникает необходимость замены символов новой строки пробелами для отображения содержимого в одной строке.
В этом случае можно использовать команду cat
для открытия файла, который затем передать команде tr
для преобразования:
Пример:
oleg@mobile:~/Directory:$ cat tr-example.txt
Бойсе
Де-Мойн
Монтгомери
Джуно
Финикс
Литл-Рок
Шайенн
Олимпия
Монтпилиер
Ричмонд
Мадисон
Гонолулу
oleg@mobile:~/Directory:$
Выполняем преобразование:
oleg@mobile:~/Directory:$ cat tr-example.txt | tr -s 'n' ' '
Бойсе Де-Мойн Монтгомери Джуно Финикс Литл-Рок Шайенн Олимпия Монтпилиер Ричмонд Мадисон Гонолулу oleg@mobile:~/Directory:$
Проверяем:
oleg@mobile:~/Directory:$ cat tr-example.txt
Бойсе
Де-Мойн
Монтгомери
Джуно
Финикс
Литл-Рок
Шайенн
Олимпия
Монтпилиер
Ричмонд
Мадисон
Гонолулу
oleg@mobile:~/Directory:$
В файле ничего не изменилось, так как вывод следует направлять в новый файл.
Сохранение вывода в файл
Повторяем предыдущий пример, но вывод перенаправим в новый файл:
oleg@mobile:~/Directory:$ cat tr-example.txt | tr -s 'n' ' ' < tr-example.txt > tr-example_2.txt
oleg@mobile:~/Directory:$
Проверяем:
oleg@mobile:~/Directory:$ cat tr-example_2.txt
Бойсе Де-Мойн Монтгомери Джуно Финикс Литл-Рок Шайенн Олимпия Монтпилиер Ричмонд Мадисон Гонолулу oleg@mobile:~/Directory:$
Всё ок!
Вывод списка уникальных слов
Вы можете вывести уникальные слова из файла с количеством их повторений:
oleg@mobile:~/Directory:$ cat linux-command-com.txt | tr -cs "[:alnum:]" "n" | sort | uniq -c | sort -rnsort | uniq -c | sort -rn
13 oleg
13 mobile
13 Directory
12 usa
12 txt
12 states
12 ru
11 1
10 comm
9 2
5 Linux
4 order
3 WY
3 WI
3 WA
3 VT
3 VA
3 ID
3 IA
3 HI
3 check
3 AZ
3 AR
3 AL
3 AK
2 sort
2 nocheck
2 cat
2 3
1 zero
1 z
1 total
1 terminated
1 output
1 orde
1 o
1 NUL
1 LC
1 delimiter
1 COLLATE
1 23
1 13
1 10
1
oleg@mobile:~/Directory:$
Заключение
Мы рассмотрели приёмы работы в Linux с командой tr
при различных преобразованиях текста. При использовании перенаправлений возможности этой утилиты значительно возрастают и поэтому она часто применяется в скриптах.
Редактор sed получает входной поток построчно, редактирует каждую строку согласно правилам, и затем выводит результат в выходной поток. Набор команд sed сделан по образцу строкового редактора ed.
Следующий пример демонстрирует типичное использование sed:
sed 's/шаблон/замена/g' inputFile > outputFile
Редактор ищет в файле inputFile
строки, содержащие шаблон
и заменяет в них найденные совпадения на замена
. Вывод перенаправляется в файл outputFile
. Буква «s» — это сокращение слова «substitute», то есть — перед нами команда замены. По умолчанию, заменяется только первое вхождение шаблона
в каждой строке. Флаг g
предписывает заменить все вхождения.
В некоторых случаях с помощью sed надо обработать лишь какую-то часть текста — некую конкретную строку или группу строк. Для достижения такой цели можно воспользоваться двумя подходами:
- Задать ограничение на номера обрабатываемых строк.
- Указать фильтр, соответствующие которому строки нужно обработать.
Указание номера одной строки, которую нужно обработать:
sed '2s/шаблон/замена/g' inputFile
Указание диапазона строк, которые нужно обработать:
sed '2,4s/шаблон/замена/g' inputFile
Обработать только строки, соответствующие фильтру:
sed '/фильтр/s/шаблон/замена/g' inputFile
Удаление строк
Редактор sed умеет не только заменять одну последовательность символов в строках на другую. Используя команду d
(от delete), можно удалять строки из текстового потока. Например, удалим третью строку:
sed '3d' inputFile
Удалить строки, начиная с заданной — и до конца файла:
sed '3,$d' inputFile
Строки можно удалять и по шаблону:
sed '/шаблон/d' inputFile
При вызове команды d
можно указывать пару шаблонов — будут удалены строки, в которых встретится шаблон, и те строки, которые находятся между ними:
sed '/первый/,/третий/d' inputFile
Вставка строк
С помощью sed
можно вставлять данные в текстовый поток, используя команды i
(от insert) и a
(от append):
- команда
i
добавляет новую строку перед заданной - команда
a
добавляет новую строку после заданной
Вызовем команды i
и a
, указав номер строки, перед/после которой надо вставить новую строку:
sed '3iЭто новая строка' inputFile
sed '5aЭто новая строка' inputFile
Замена строк
Команда c
(от change) позволяет изменить содержимое целой строки текста в потоке данных. При её вызове нужно указать номер строки, вместо которой в поток надо добавить новые данные:
sed '3cЭто измененная строка' inputFile
Если воспользоваться при вызове команды шаблоном в виде обычного текста или регулярного выражения, заменены будут все соответствующие шаблону строки:
sed '/шаблон/c Новая строка вместо старых' inputFile
Замена символов
Команда y
работает с отдельными символами, заменяя их в соответствии с переданными ей при вызове данными:
sed 'y/1234/5678/' inputFile
Регулярные выражения
Редактор sed поддерживает два типа регулярных выражений: базовый (BRE — basic regular expressions) и расширенный (ERE — extended regular expressions). По умолчанию sed использует базовый тип регулярных выражений.
В BRE распознаются следующие метасимволы:
^ $ . [ ] *
Все другие символы расцениваются как литералы. В ERE добавлены следующие метасимволы (и связанные с ними функции):
( ) { } ? + |
Тем не менее, символы «(», «)», «{» и «}» в BRE обрабатываются как метасимволы, если они экранированы обратным слешом; в то время как в ERE постановка перед любыми метасимволами обратного слеша приводит к тому, что они трактуются как литералы.
Опция -r редактора sed позволяет использовать расширенные регулярные выражения.
Опции редактора sed
Опция -n подавляет вывод. Чтобы получить вывод нужно специальное указание, например, команда p
(от print).
Опция -e позволяет выполнить несколько команд, например:
sed -e 's/шаблон1/замена1/' -e 's/шаблон2/замена2/' inputFile
Опция -f позволяет выполнить большое количество команд, записанных в файл:
sed -f commandFile inputFile
# этот скрипт изменит все строчные гласные буквы на заглавные s/a/A/g s/e/E/g s/i/I/g s/o/O/g s/u/U/g
Несколько примеров использования
Замена без использования модификатора g
:
$ echo 'кот этот, был самый обычный кот' | sed 's/кот/котенок/' котенок этот, был самый обычный кот
А теперь с модификатором глобальной замены:
$ echo 'кот этот, был самый обычный кот' | sed 's/кот/котенок/g' котенок этот, был самый обычный котенок
Заключить все слова в скобки (&
или означает найденное совпадение с шаблоном):
$ echo 'глупый пингвин робко прячет' | sed 's/[^ ]*/(&)/g' (глупый) (пингвин) (робко) (прячет)
Поменять слова местами:
$ echo 'глупый пингвин' | sed 's/([а-я]*) ([а-я]*)/2 1/' пингвин глупый
Обратите внимание — чтобы захватить части совпадений в карманы, используются круглые скобки с экранированием (…)
— вот так странно работают регулярные выражения BRE.
Заменяем второе слово в строке (число после последнего разделителя указывает, какое по счету совпадение подлежит замене):
$ echo очень глупый пингвин | sed 's/[а-я]*/хороший/2' очень хороший пингвин
Заменяем второе и все следующие слова:
$ echo очень глупый пингвин | sed 's/[а-я]*/хороший/2g' очень хороший хороший
Удалить все слова, кроме первого:
$ echo 'очень глупый пингвин' | sed 's/[^ ]*//2g' очень
Показать строки со 2 по 4:
$ cat unix.txt The Unix operating system was pioneered by Ken Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in the design of the Unix system was to create an environment that promoted efficient program development. $ sed -n '2,4p' unix.txt Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in the design of the Unix system was to create an
Удалить строки со 2 по 4:
$ sed '2,4d' unix.txt The UNIX operating system was pioneered by Ken environment that promoted efficient program development.
Удалить все строки, содержащие текст «Unix»:
$ sed '/Unix/d' unix.txt Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in environment that promoted efficient program development.
Удалить последние три символа из каждой строки:
$ sed 's/...$//' unix.txt The Unix operating system was pioneered by Thompson and Dennis Ritchie at Bell Laborator in the late 1960s. One of the primary goals the design of the Unix system was to create environment that promoted efficient prog developme
Добавить три *
в начало каждой строки:
$ sed 's/^/***/' unix.txt ***The Unix operating system was pioneered by Ken ***Thompson and Dennis Ritchie at Bell Laboratories ***in the late 1960s. One of the primary goals in ***the design of the Unix system was to create an ***environment that promoted efficient program ***development.
Удалить строки, содержащие цифры:
$ sed '/[0-9]/d' unix.txt The Unix operating system was pioneered by Ken Thompson and Dennis Ritchie at Bell Laboratories the design of the Unix system was to create an environment that promoted efficient program development.
Заменить первое вхождение «Unix» на «UNIX» во всех строках, содержащих «design»
$ sed '/design/s/Unix/UNIX/' unix.txt The Unix operating system was pioneered by Ken Thompson and Dennis Ritchie at Bell Laboratories in the late 1960s. One of the primary goals in the design of the UNIX system was to create an environment that promoted efficient program development.
Поиск:
Linux • RegExp • Команда • Редактор • Шаблон
Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Потоковый редактор sed (stream editor) — это текстовый редактор, выполняющий операции редактирования над информацией в стандартном потоке ввода или файле. Редактирование осуществляется по одной строке и неинтерактивно. Это означает, что вы принимаете все решения по редактированию при запуске команды, а утилита автоматически выполняет ваши указания. Это может показаться непонятным и неинтуитивным, но на самом деле sed — очень мощный и быстрый инструмент для преобразования текста.
В данном руководстве мы рассмотрим ряд базовых операций и познакомимся с необходимым синтаксисом. Утилита вряд ли заменит ваш обычный текстовый редактор, но скорее всего станет полезным дополнением к вашим инструментам для работы с текстами.
Содержание
- Синтаксис Sed
- Вывод строк
- Диапазоны адресов
- Удаление текста
- Замена текста
- Заключение
Обычно sed работает с потоком текста, считываемым из стандартного ввода или файла. Это значит, что вы можете отправить выходные данные другой команды непосредственно на вход утилиты для редактирования или работать с уже созданным файлом. Вывод всех результатов по умолчанию осуществляется в стандартный поток вывода, то есть выходные данные будут выведены на экран, а не сохранены в файл, если их не перенаправить.
Синтаксис команды следующий:
sed [опции] команды [файл-для-редактирования]
Скопируем себе в домашнюю директорию несколько файлов, чтобы попрактиковаться в редактировании.
cd cp /usr/share/common-licenses/BSD . cp /usr/share/common-licenses/GPL-3 .
Воспользуемся утилитой для просмотра содержимого скопированной нам лицензии BSD. По умолчанию sed выводит результаты на экран, поэтому им можно пользоваться для просмотра файлов, не задавая команд редактирования:
sed '' BSD Copyright (c) The Regents of the University of California. All rights reserved.Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. ... ...
Это работает из-за того, что одиночные кавычки содержат команды редактирования, передаваемые sed. Мы ничего не передали, поэтому утилита просто вывела каждую полученную строку в стандартный поток вывода. Теперь покажем, как утилита может использовать стандартный ввод. Перенаправим редактору выходные данные команды “cat” и получим тот же результат.
cat BSD | sed ''
Copyright (c) The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
. . .
. . .
Мы можем работать с файлами или потоками текста (как происходит при перенаправлении вывода символом «|») одинаково легко.
Вывод строк
В предыдущем примере мы показали, что передаваемые без команд входные данные напрямую выводятся в стандартный поток вывода.Теперь рассмотрим явную команду “print”, которая задаётся при помощи символа “p” в одиночных кавычках.
sed 'p' BSD Copyright (c) The Regents of the University of California. Copyright (c) The Regents of the University of California. All rights reserved. All rights reserved. Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions modification, are permitted provided that the following conditions are met: are met: . . . . . .
Теперь утилита выводит каждую строку дважды. Это происходит потому, что каждая строка выводится автоматически, а ещё мы в явном виде указали выводить их командой “p”. Если посмотреть на результат, где дважды напечатана первая строка, затем дважды вторая и т.д., можно заметить, что sed работает построчно. Он принимает строку, обрабатывает ее и выводит результат, затем процесс повторяется для следующей строки.
Указав sed опцию «-n», которая отключает автоматический вывод, мы можем очистить результат:
sed -n 'p' BSD Copyright (c) The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. . . . . . .
Каждая строка снова выводится один раз.
Диапазоны адресов
Рассмотренные выше примеры вряд ли можно назвать редактированием (если мы не хотели выводить каждую строку два раза). Давайте изменим результат, указав sed напечатать только первую строку.
sed -n '1p' BSD Copyright (c) The Regents of the University of California.
Число «1» перед командой вывода указывает номер строки для работы. Таким же образом мы можем вывести пять строк (не забываем про «-n»).
sed -n '1,5p' BSD Copyright (c) The Regents of the University of California. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions
Мы только что передали в утилиту адрес. При получении адреса редактор выполняет указанные далее команды только над этими строками. В данном примере мы указали начальный адрес и смещение, чтобы сообщить команде, сколько ещё строк она должна пройти:
sed -n '1,+4p' BSD
Результат будет таким же, потому что мы указали начать с первой строки и обработать следующие 4.
Если нужно исключить какие-то строки, можно указать интервал после символа «~».
Следующая команда напечатает все нечетные строки, начиная с первой:
sed -n '1~2p' BSD Copyright (c) The Regents of the University of California. modification, are permitted provided that the following conditions 1. Redistributions of source code must retain the above copyright 2. Redistributions in binary form must reproduce the above copyright documentation and/or other materials provided with the distribution. may be used to endorse or promote products derived from this software . . . . . .
Удаление текста
Можно легко удалить текст, который мы выводили в предыдущем примере, заменив команду “p” на команду “d”. Команда «-n» нам больше не нужна, потому что при использовании команды удаления утилита выводит все, что не удалено. Это позволяет нам видеть, что происходит. Изменим последнюю команду из предыдущего раздела так, чтобы она удаляла все нечетные строки, начиная с первой. В результате мы должны получить все строки, которые не были выведены в прошлый раз.
sed '1~2d' BSD All rights reserved. Redistribution and use in source and binary forms, with or without are met: notice, this list of conditions and the following disclaimer. notice, this list of conditions and the following disclaimer in the 3. Neither the name of the University nor the names of its contributors without specific prior written permission. . . . . . .
При этом исходный файл не меняется. Результаты редактирования просто выводятся на экран. Если результат нужно сохранить, можно перенаправить стандартный вывод в файл:
sed '1~2d' BSD > everyother.txt
Открыв этот файл командой cat, мы увидим тот же результат, который был на экране после выполнения предыдущей команды. По умолчанию sed не редактирует исходный файл в целях безопасности. Это можно изменить при помощи опции «-i», которая означает редактирование на месте. Исходный файл будет изменен. Давайте попробуем отредактировать только что созданный нами файл «everyother.txt». Снова удалим все нечетные строки:
sed -i '1~2d' everyother.txt
При помощи cat можно убедиться, что файл был отредактирован.
Опция “-i” может быть опасной, но утилита предоставляет возможность создания резервной копии перед редактированием. Для этого сразу после опции “-i” укажите расширение резервной копии “.bak”:
sed -i.bak '1~2d' everyother.txt
Будет создан файл резервной копии с расширением “bak”, а затем выполнено редактирование исходного файла.
Замена текста
Чаще всего sed используется для замены текста. Редактор позволяет осуществлять поиск текста по шаблону при помощи регулярных выражений. А затем заменять найденный текст. В простейшем варианте можно заменить одно слово на другое, используя следующий синтаксис:
's/старое_слово/новое_слово/'
Параметр «s» – это команда замены. Три слэша (/) нужны для разделения различных текстовых полей. Если вам удобно, вы можете использовать для этого другие символы. Например, если нам нужно изменить имя веб-сайта, удобнее использовать другой разделитель, так как URL содержат слэши. Воспользуемся командой echo для передачи примера:
echo "http://www.example.com/index.html" | sed 's_com/index_org/home_' http://www.example.org/home.html
Здесь секция «com/index» заменяется на «org/home». В качестве разделителя используется нижнее подчеркивание «_». Не забудьте про последний разделитель, иначе sed выдаст ошибку.
echo "http://www.example.com/index.html" | sed 's_com/index_org/home' sed: -e expression #1, char 22: unterminated `s' command
Создадим файл для отработки замен:
echo "this is the song that never ends yes, it goes on and on, my friend some people started singing it not knowing what it was and they'll continue singing it forever just because..." > annoying.txt
Теперь заменим «on» на «forward»
sed 's/on/forward/' annoying.txt this is the sforwardg that never ends yes, it goes forward and on, my friend some people started singing it not knowing what it was and they'll cforwardtinue singing it forever just because...
Стоит обратить внимание на ряд моментов. Во-первых, мы заменяем шаблоны, а не слова. “on” в слове “song” было заменено на “forward”. Во-вторых, второе “on” в строке 2 заменено не было. Это произошло потому, что по умолчанию команда “s” обрабатывает первое совпадение в строке. А затем переходит к следующей строке. Для замены каждого “on”, а не только первого в строке, можно указать команде замены флаг “g” после шаблонов:
sed 's/on/forward/g' annoying.txt this is the sforwardg that never ends yes, it goes forward and forward, my friend some people started singing it not knowing what it was and they'll cforwardtinue singing it forever just because...
Теперь были заменены все “on”. Чтобы заменить только вторые “on” в каждой строке, вместо “g” нужно указать “2”:
sed 's/on/forward/2' annoying.txt this is the song that never ends yes, it goes on and forward, my friend some people started singing it not knowing what it was and they'll continue singing it forever just because...
Если нам нужно вывести только те строки, где выполнялась замена, для отмены автоматического вывода можно снова воспользоваться опцией «-n». Затем мы можем передать флаг “p” для вывода строк, в которых производились замены.
sed -n 's/on/forward/2p' annoying.text yes, it goes on and forward, my friend
Пример показывает, что флаги в конце команды можно комбинировать. Чтобы игнорировать регистр, нужно указать флаг “i”.
sed 's/SINGING/saying/i' annoying.txt this is the song that never ends yes, it goes on and on, my friend some people started saying it not knowing what it was and they'll continue saying it forever just because...
Если нужно заменить текст во всех файлах директории то можно воспользоваться командой
grep 'текс' -P -R -I -l * | xargs sed -i 's/текст_который_нужно_искать/текст/g'
Про утилиту grep можно прочитать здесь
Заключение
Мы рассмотрели основы использования sed. Теперь вы можете быстро редактировать текстовые документы при помощи соответствующих команд sed.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
При работе с текстовыми файлами вам часто нужно искать и заменять строки текста в одном или нескольких файлах.
sed
является s Tream ред itor. Он может выполнять базовые операции с текстом над файлами и входными потоками, такими как конвейеры. С помощью sed
вы можете искать, находить и заменять, вставлять и удалять слова и строки. Он поддерживает базовые и расширенные регулярные выражения, которые позволяют сопоставлять сложные шаблоны.
В этой статье мы поговорим о том, как найти и заменить строки с помощью sed
. Мы также покажем вам, как выполнить рекурсивный поиск и замену.
Найти и заменить строку с помощью sed
Существует несколько версий sed
с некоторыми функциональными различиями. macOS использует версию BSD, в то время как большинство дистрибутивов Linux поставляются с предустановленной по умолчанию GNU sed
. Мы будем использовать версию GNU.
Общая форма поиска и замены текста с помощью sed
имеет следующий вид:
sed -i 's/SEARCH_REGEX/REPLACEMENT/g' INPUTFILE
-i
— По умолчаниюsed
записывает свой вывод в стандартный вывод. Эта опция указываетsed
редактировать файлы на месте. Если указано расширение (например, -i.bak), создается резервная копия исходного файла.-
s
— Заменяющая команда, вероятно, наиболее часто используемая команда в sed. -
/ / /
— Символ-разделитель. Это может быть любой символ, но обычно используется символ косой черты (/
). -
SEARCH_REGEX
— обычная строка или регулярное выражение для поиска. -
REPLACEMENT
— строка замены. -
g
— Флаг глобальной замены. По умолчаниюsed
читает файл построчно и изменяет только первое вхождениеSEARCH_REGEX
в строке. Если указан флаг замены, заменяются все вхождения. -
INPUTFILE
— имя файла, для которого вы хотите запустить команду.
Рекомендуется заключать аргумент в кавычки, чтобы метасимволы оболочки не расширялись.
Давайте посмотрим, как мы можем использовать команду sed
для поиска и замены текста в файлах некоторыми из наиболее часто используемых параметров и флагов.
В демонстрационных целях мы будем использовать следующий файл:
file.txt
123 Foo foo foo
foo /bin/bash Ubuntu foobar 456
Если флаг g
опущен, заменяется только первый экземпляр строки поиска в каждой строке:
sed -i 's/foo/linux/' file.txt
123 Foo linux foo
linux /bin/bash Ubuntu foobar 456
С флагом глобальной замены sed
заменяет все вхождения шаблона поиска:
sed -i 's/foo/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu linuxbar 456
Как вы могли заметить, подстрока foo
внутри строки foobar
также заменена в предыдущем примере. Если это нежелательное поведение, используйте выражение границы слова ( b
) на обоих концах строки поиска. Это гарантирует, что частичные слова не совпадают.
sed -i 's/bfoob/linux/g' file.txt
123 Foo linux linux
linux /bin/bash Ubuntu foobar 456
Чтобы сделать совпадение с шаблоном нечувствительным к регистру, используйте флаг I
В приведенном ниже примере мы используем флаги g
и I
sed -i 's/foo/linux/gI' file.txt
123 linux linux linux
linux /bin/bash Ubuntu linuxbar 456
Если вы хотите найти и заменить строку, содержащую символ-разделитель ( /
), вам нужно будет использовать обратную косую черту ( ), чтобы избежать косой черты. Например, чтобы заменить
/bin/bash
на /usr/bin/zsh
вы должны использовать
sed -i 's//bin/bash//usr/bin/zsh/g' file.txt
Более простой и понятный вариант — использовать другой символ-разделитель. Большинство людей используют вертикальную полосу ( |
) или двоеточие ( :
) , но вы можете использовать любой другой символ:
sed -i 's|/bin/bash|/usr/bin/zsh|g' file.txt
123 Foo foo foo
foo /usr/bin/zsh Ubuntu foobar 456
Вы также можете использовать регулярные выражения. Например, чтобы найти все трехзначные числа и заменить их строковым number
вы должны использовать:
sed -i 's/b[0-9]{3}b/number/g' file.txt
number Foo foo foo
foo /bin/bash demo foobar number
Еще одна полезная функция sed заключается в том, что вы можете использовать символ амперсанда &
который соответствует сопоставленному шаблону. Персонаж можно использовать несколько раз.
Например, если вы хотите добавить фигурные скобки {}
вокруг каждого трехзначного числа, введите:
sed -i 's/b[0-9]{3}b/{&}/g' file.txt
{123} Foo foo foo
foo /bin/bash demo foobar {456}
И последнее, но не менее важное: всегда рекомендуется делать резервную копию при редактировании файла с помощью sed
. Для этого просто укажите расширение файла резервной копии для параметра -i
. Например, чтобы отредактировать file.txt
и сохранить исходный файл как file.txt.bak
вы должны использовать:
sed -i.bak 's/foo/linux/g' file.txt
Чтобы убедиться, что резервная копия создана, выведите список файлов с помощью команды ls
:
ls
file.txt file.txt.bak
Рекурсивный поиск и замена
Иногда может потребоваться рекурсивный поиск в каталогах файлов, содержащих строку, и замена строки во всех файлах. Это можно сделать с помощью таких команд, как find
или grep
для рекурсивного поиска файлов в каталоге и передачи имен файлов в sed
.
Следующая команда будет рекурсивно искать файлы в текущем рабочем каталоге и передавать имена файлов в sed
.
find . -type f -exec sed -i 's/foo/bar/g' {} +
Чтобы избежать проблем с файлами, содержащими пробелы в своих именах, используйте параметр -print0
, который указывает find
напечатать имя файла, за которым следует нулевой символ, и xargs -0
вывод в sed
используя xargs -0
:
find . -type f -print0 | xargs -0 sed -i 's/foo/bar/g'
Чтобы исключить каталог, используйте параметр -not -path
. Например, если вы заменяете строку в локальном репозитории git, чтобы исключить все файлы, начинающиеся с точки ( .
), Используйте:
find . -type f -not -path '*/.*' -print0 | xargs -0 sed -i 's/foo/bar/g'
Если вы хотите искать и заменять текст только в файлах с определенным расширением, вы будете использовать:
find . -type f -name "*.md" -print0 | xargs -0 sed -i 's/foo/bar/g'
Другой вариант — использовать команду grep
для рекурсивного поиска всех файлов, содержащих шаблон поиска, а затем передать имена файлов в sed
:
grep -rlZ 'foo' . | xargs -0 sed -i.bak 's/foo/bar/g'
Выводы
Хотя это может показаться сложным и сложным, поначалу поиск и замена текста в файлах с помощью sed
очень просты.
Чтобы узнать больше о sed
команд, опций и флагов, посетить GNU СЭД руководство и Grymoire СЭД учебник .
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.