[Перевод] Команда SED в Linux/Unix с примерами

ru0gcn3hurbqakyomydzdh42m8e.png


Компиляция из двух смежных статей на тему использования команды 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 
xpu7zibhbhdbw7-lkbpvegia4_c.png

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

oug5kh6sjydt9llengsiebnp40w.png

© Habrahabr.ru