Как исправить строку в ubuntu

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

В данном руководстве мы рассмотрим ряд базовых операций и познакомимся с необходимым синтаксисом. Утилита вряд ли заменит ваш обычный текстовый редактор, но скорее всего станет полезным дополнением к вашим инструментам для работы с текстами.

Содержание

  1. Синтаксис Sed
  2. Вывод строк
  3. Диапазоны адресов
  4. Удаление текста
  5. Замена текста
  6. Заключение

Обычно 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 СЭД учебник .

Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.

Добавить комментарий