[Перевод] Команда SED в Linux/Unix с примерами
Компиляция из двух смежных статей на тему использования команды 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