Introduction
The sed (stream editor) utility is a line-oriented text parsing and transformation tool. The sed
command uses a simple programming language and regular expressions to process text streams and files. The most used feature of the sed
command is string substitution.
This guide shows how to use sed
to find and replace strings through examples.
Prerequisites
- Access to the command line/terminal.
- A text file (this guide provides an example.txt file).
- Basic terminal commands (grab our free cheat sheet).
The syntax to find and replace text using the sed
command is:
sed -i 's/<search regex>/<replacement>/g' <input file>
The command consists of the following:
-i
tells thesed
command to write the results to a file instead of standard output.s
indicates the substitute command./
is the most common delimiter character. The command also accepts other characters as delimiters, which is useful when the string contains forward slashes.<search regex>
is the string or regular expression search parameter.<replacement>
is the replacement text.g
is the global replacement flag, which replaces all occurrences of a string instead of just the first.<input file>
is the file where the search and replace happens.
The single quotes help avoid meta-character expansion in the shell.
The BDS version of sed
(which includes macOS) does not support case-insensitive matching or file replacement. The command for file replacement looks like this:
sed 's/<search regex>/<replacement>/g' <input file> > <output file>
Alternatively, install the GNU version of sed
on macOS with homebrew:
brew install gnu-sed
Run the GNU sed
command as follows:
gsed -i 's/<search regex>/<replacement>/g' <input file>
Replace the sed
command with gsed
to follow the examples below.
sed Replace Examples
The examples from this guide use a sample file to replace strings.
1. Create a sample text file:
nano example.txt
2. Add the following contents:
foobarbazfoobarbaz
foo bar baz foo bar baz
Foo Bar Baz Foo Bar Baz
FOO BAR BAZ FOO BAR BAZ
/foo/bar/baz /foo/bar/baz
Use the file as input to test the examples below.
Replace First Matched String
1. To replace the first found instance of the word bar with linux in every line of a file, run:
sed -i 's/bar/linux/' example.txt
2. The -i
tag inserts the changes to the example.txt file. Check the file contents with the cat command:
cat example.txt
The command replaces the first instance of bar with linux in every line, including substrings. The match is exact, ignoring capitalization variations.
Global Replace
To replace every string match in a file, add the g
flag to the script. For example:
sed -i 's/bar/linux/g' example.txt
The command globally replaces every instance of bar with linux in the file.
Match and Replace All Cases
To find and replace all instances of a word and ignore capitalization, use the I
parameter:
sed -i 's/bar/linux/gI' example.txt
The command replaces all instances of the word bar in the text, ignoring capitalization.
Ignore Substrings
Add word boundaries (b
) to the sed
command to ignore substrings when replacing strings in a file. For example:
sed -i 's/bbarb/linux/gI' example.txt
Alternatively, change the delimiter to make the command easier to read:
sed -i 's:bbarb:linux:gI' example.txt
The command ignores substrings, matching only the whole word.
Find and Replace Strings With Slashes
Escape the forward slash character to find and replace a string with slashes. For example, to replace /foo/bar/baz with /home/kb, use the following syntax:
sed -i 's//foo/bar/baz//home/kb/g' example.txt
Alternatively, change the delimiter to avoid escaping characters:
sed -i 's:/foo/bar/baz:/home/kb:g' example.txt
Use this syntax to replace paths and other strings with slashes.
Find and Replace with Regular Expressions
The search pattern for the sed
command accepts regular expressions, similar to grep regex. For example, to match all capital letters and replace them with 5, use:
sed -i 's/[A-Z]/5/g' example.txt
The regex pattern helps find all capital letters and replaces them with the number in the file.
Reference Found String
Use the ampersand character (&
) to reference the found string. For example, to add a forward slash (/) before every instance of foo in a file, use:
sed -i 's/foo//&/gI'example.txt
Instead of retyping the search parameter, the &
sign references the found string.
Create a Backup
To create a backup file before overwriting the existing one, add the .bak
parameter to the -i
tag.
sed -i.bak 's/foo/FOO/g' example.txt
The command creates a backup (example.txt.bak
) before overwriting the original. Use this method to keep a copy in the original format and avoid overwriting.
Recursive Find and Replace
Use the find command to search for files and combine it with sed
to replace strings in files recursively. For example:
find -name 'example*' -exec sed -i 's/[a-z]/5/gI' {} +
The command finds all files starting with example and executes the sed
command on the files. The executed command replaces all letters with 5, ignoring capitalization.
Conclusion
After going through the examples in this guide, you know how to use sed
to replace strings in files. The sed
command is a powerful text manipulation utility with many advanced features.
Next, check out the awk or gawk command to learn about other text manipulation tools.
Время на прочтение
9 мин
Количество просмотров 522K
Bash-скрипты: начало
Bash-скрипты, часть 2: циклы
Bash-скрипты, часть 3: параметры и ключи командной строки
Bash-скрипты, часть 4: ввод и вывод
Bash-скрипты, часть 5: сигналы, фоновые задачи, управление сценариями
Bash-скрипты, часть 6: функции и разработка библиотек
Bash-скрипты, часть 7: sed и обработка текстов
Bash-скрипты, часть 8: язык обработки данных awk
Bash-скрипты, часть 9: регулярные выражения
Bash-скрипты, часть 10: практические примеры
Bash-скрипты, часть 11: expect и автоматизация интерактивных утилит
В прошлый раз мы говорили о функциях в bash-скриптах, в частности, о том, как вызывать их из командной строки. Наша сегодняшняя тема — весьма полезный инструмент для обработки строковых данных — утилита Linux, которая называется sed. Её часто используют для работы с текстами, имеющими вид лог-файлов, конфигурационных и других файлов.
Если вы, в bash-скриптах, каким-то образом обрабатываете данные, вам не помешает знакомство с инструментами sed и gawk. Тут мы сосредоточимся на sed и на работе с текстами, так как это — очень важный шаг в нашем путешествии по бескрайним просторам разработки bash-скриптов.
Сейчас мы разберём основы работы с sed, а так же рассмотрим более трёх десятков примеров использования этого инструмента.
Основы работы с sed
Утилиту sed называют потоковым текстовым редактором. В интерактивных текстовых редакторах, наподобие nano, с текстами работают, используя клавиатуру, редактируя файлы, добавляя, удаляя или изменяя тексты. Sed позволяет редактировать потоки данных, основываясь на заданных разработчиком наборах правил. Вот как выглядит схема вызова этой команды:
$ sed options file
По умолчанию sed применяет указанные при вызове правила, выраженные в виде набора команд, к STDIN
. Это позволяет передавать данные непосредственно sed.
Например, так:
$ echo "This is a test" | sed 's/test/another test/'
Вот что получится при выполнении этой команды.
Простой пример вызова sed
В данном случае sed заменяет слово «test» в строке, переданной для обработки, словами «another test». Для оформления правила обработки текста, заключённого в кавычки, используются прямые слэши. В нашем случае применена команда вида s/pattern1/pattern2/
. Буква «s» — это сокращение слова «substitute», то есть — перед нами команда замены. Sed, выполняя эту команду, просмотрит переданный текст и заменит найденные в нём фрагменты (о том — какие именно, поговорим ниже), соответствующие pattern1
, на pattern2
.
Выше приведён примитивный пример использования sed, нужный для того, чтобы ввести вас в курс дела. На самом деле, sed можно применять в гораздо более сложных сценариях обработки текстов, например — для работы с файлами.
Ниже показан файл, в котором содержится фрагмент текста, и результаты его обработки такой командой:
$ sed 's/test/another test' ./myfile
Текстовый файл и результаты его обработки
Здесь применён тот же подход, который мы использовали выше, но теперь sed обрабатывает текст, хранящийся в файле. При этом, если файл достаточно велик, можно заметить, что sed обрабатывает данные порциями и выводит то, что обработано, на экран, не дожидаясь обработки всего файла.
Sed не меняет данные в обрабатываемом файле. Редактор читает файл, обрабатывает прочитанное, и отправляет то, что получилось, в STDOUT
. Для того, чтобы убедиться в том, что исходный файл не изменился, достаточно, после того, как он был передан sed, открыть его. При необходимости вывод sed можно перенаправить в файл, возможно — перезаписать старый файл. Если вы знакомы с одним из предыдущих материалов этой серии, где речь идёт о перенаправлении потоков ввода и вывода, вы вполне сможете это сделать.
Выполнение наборов команд при вызове sed
Для выполнения нескольких действий с данными, используйте ключ -e
при вызове sed. Например, вот как организовать замену двух фрагментов текста:
$ sed -e 's/This/That/; s/test/another test/' ./myfile
Использование ключа -e при вызове sed
К каждой строке текста из файла применяются обе команды. Их нужно разделить точкой с запятой, при этом между окончанием команды и точкой с запятой не должно быть пробела.
Для ввода нескольких шаблонов обработки текста при вызове sed, можно, после ввода первой одиночной кавычки, нажать Enter, после чего вводить каждое правило с новой строки, не забыв о закрывающей кавычке:
$ sed -e '
> s/This/That/
> s/test/another test/' ./myfile
Вот что получится после того, как команда, представленная в таком виде, будет выполнена.
Другой способ работы с sed
Чтение команд из файла
Если имеется множество команд sed, с помощью которых надо обработать текст, обычно удобнее всего предварительно записать их в файл. Для того, чтобы указать sed файл, содержащий команды, используют ключ -f
:
Вот содержимое файла mycommands
:
s/This/That/
s/test/another test/
Вызовем sed, передав редактору файл с командами и файл для обработки:
$ sed -f mycommands myfile
Результат при вызове такой команды аналогичен тому, который получался в предыдущих примерах.
Использование файла с командами при вызове sed
Флаги команды замены
Внимательно посмотрите на следующий пример.
$ sed 's/test/another test/' myfile
Вот что содержится в файле, и что будет получено после его обработки sed.
Исходный файл и результаты его обработки
Команда замены нормально обрабатывает файл, состоящий из нескольких строк, но заменяются только первые вхождения искомого фрагмента текста в каждой строке. Для того, чтобы заменить все вхождения шаблона, нужно использовать соответствующий флаг.
Схема записи команды замены при использовании флагов выглядит так:
s/pattern/replacement/flags
Выполнение этой команды можно модифицировать несколькими способами.
- При передаче номера учитывается порядковый номер вхождения шаблона в строку, заменено будет именно это вхождение.
- Флаг
g
указывает на то, что нужно обработать все вхождения шаблона, имеющиеся в строке. - Флаг
p
указывает на то, что нужно вывести содержимое исходной строки. - Флаг вида
w file
указывает команде на то, что нужно записать результаты обработки текста в файл.
Рассмотрим использование первого варианта команды замены, с указанием позиции заменяемого вхождения искомого фрагмента:
$ sed 's/test/another test/2' myfile
Вызов команды замены с указанием позиции заменяемого фрагмента
Тут мы указали, в качестве флага замены, число 2. Это привело к тому, что было заменено лишь второе вхождение искомого шаблона в каждой строке. Теперь опробуем флаг глобальной замены — g
:
$ sed 's/test/another test/g' myfile
Как видно из результатов вывода, такая команда заменила все вхождения шаблона в тексте.
Глобальная замена
Флаг команды замены p
позволяет выводить строки, в которых найдены совпадения, при этом ключ -n
, указанный при вызове sed, подавляет обычный вывод:
$ sed -n 's/test/another test/p' myfile
Как результат, при запуске sed в такой конфигурации на экран выводятся лишь строки (в нашем случае — одна строка), в которых найден заданный фрагмент текста.
Использование флага команды замены p
Воспользуемся флагом w
, который позволяет сохранить результаты обработки текста в файл:
$ sed 's/test/another test/w output' myfile
Сохранение результатов обработки текста в файл
Хорошо видно, что в ходе работы команды данные выводятся в STDOUT, при этом обработанные строки записываются в файл, имя которого указано после w
.
Символы-разделители
Представьте, что нужно заменить /bin/bash
на /bin/csh
в файле /etc/passwd
. Задача не такая уж и сложная:
$ sed 's//bin/bash//bin/csh/' /etc/passwd
Однако, выглядит всё это не очень-то хорошо. Всё дело в том, что так как прямые слэши используются в роли символов-разделителей, такие же символы в передаваемых sed строках приходится экранировать. В результате страдает читаемость команды.
К счастью, sed позволяет нам самостоятельно задавать символы-разделители для использования их в команде замены. Разделителем считается первый символ, который будет встречен после s
:
$ sed 's!/bin/bash!/bin/csh!' /etc/passwd
В данном случае в качестве разделителя использован восклицательный знак, в результате код легче читать и он выглядит куда опрятнее, чем прежде.
Выбор фрагментов текста для обработки
До сих пор мы вызывали sed для обработки всего переданного редактору потока данных. В некоторых случаях с помощью sed надо обработать лишь какую-то часть текста — некую конкретную строку или группу строк. Для достижения такой цели можно воспользоваться двумя подходами:
- Задать ограничение на номера обрабатываемых строк.
- Указать фильтр, соответствующие которому строки нужно обработать.
Рассмотрим первый подход. Тут допустимо два варианта. Первый, рассмотренный ниже, предусматривает указание номера одной строки, которую нужно обработать:
$ sed '2s/test/another test/' myfile
Обработка только одной строки, номер который задан при вызове sed
Второй вариант — диапазон строк:
$ sed '2,3s/test/another test/' myfile
Обработка диапазона строк
Кроме того, можно вызвать команду замены так, чтобы файл был обработан начиная с некоей строки и до конца:
$ sed '2,$s/test/another test/' myfile
Обработка файла начиная со второй строки и до конца
Для того, чтобы обрабатывать с помощью команды замены только строки, соответствующие заданному фильтру, команду надо вызвать так:
$ sed '/likegeeks/s/bash/csh/' /etc/passwd
По аналогии с тем, что было рассмотрено выше, шаблон передаётся перед именем команды s
.
Обработка строк, соответствующих фильтру
Тут мы использовали очень простой фильтр. Для того, чтобы в полной мере раскрыть возможности данного подхода, можно воспользоваться регулярными выражениями. О них мы поговорим в одном из следующих материалов этой серии.
Удаление строк
Утилита sed годится не только для замены одних последовательностей символов в строках на другие. С её помощью, а именно, используя команду d
, можно удалять строки из текстового потока.
Вызов команды выглядит так:
$ sed '3d' myfile
Мы хотим, чтобы из текста была удалена третья строка. Обратите внимание на то, что речь не идёт о файле. Файл останется неизменным, удаление отразится лишь на выводе, который сформирует sed.
Удаление третьей строки
Если при вызове команды d
не указать номер удаляемой строки, удалены будут все строки потока.
Вот как применить команду d
к диапазону строк:
$ sed '2,3d' myfile
Удаление диапазона строк
А вот как удалить строки, начиная с заданной — и до конца файла:
$ sed '3,$d' myfile
Удаление строк до конца файла
Строки можно удалять и по шаблону:
$ sed '/test/d' myfile
Удаление строк по шаблону
При вызове d
можно указывать пару шаблонов — будут удалены строки, в которых встретится шаблон, и те строки, которые находятся между ними:
$ sed '/second/,/fourth/d' myfile
Удаление диапазона строк с использованием шаблонов
Вставка текста в поток
С помощью sed можно вставлять данные в текстовый поток, используя команды i
и a
:
- Команда
i
добавляет новую строку перед заданной. - Команда
a
добавляет новую строку после заданной.
Рассмотрим пример использования команды i
:
$ echo "Another test" | sed 'iFirst test '
Команда i
Теперь взглянем на команду a
:
$ echo "Another test" | sed 'aFirst test '
Команда a
Как видно, эти команды добавляют текст до или после данных из потока. Что если надо добавить строку где-нибудь посередине?
Тут нам поможет указание номера опорной строки в потоке, или шаблона. Учтите, что адресация строк в виде диапазона тут не подойдёт. Вызовем команду i
, указав номер строки, перед которой надо вставить новую строку:
$ sed '2iThis is the inserted line.' myfile
Команда i с указанием номера опорной строки
Проделаем то же самое с командой a
:
$ sed '2aThis is the appended line.' myfile
Команда a с указанием номера опорной строки
Обратите внимание на разницу в работе команд i
и a
. Первая вставляет новую строку до указанной, вторая — после.
Замена строк
Команда c
позволяет изменить содержимое целой строки текста в потоке данных. При её вызове нужно указать номер строки, вместо которой в поток надо добавить новые данные:
$ sed '3cThis is a modified line.' myfile
Замена строки целиком
Если воспользоваться при вызове команды шаблоном в виде обычного текста или регулярного выражения, заменены будут все соответствующие шаблону строки:
$ sed '/This is/c This is a changed line of text.' myfile
Замена строк по шаблону
Замена символов
Команда y
работает с отдельными символами, заменяя их в соответствии с переданными ей при вызове данными:
$ sed 'y/123/567/' myfile
Замена символов
Используя эту команду, нужно учесть, что она применяется ко всему текстовому потоку, ограничить её конкретными вхождениями символов нельзя.
Вывод номеров строк
Если вызвать sed, использовав команду =
, утилита выведет номера строк в потоке данных:
$ sed '=' myfile
Вывод номеров строк
Потоковый редактор вывел номера строк перед их содержимым.
Если передать этой команде шаблон и воспользоваться ключом sed -n
, выведены будут только номера строк, соответствующих шаблону:
$ sed -n '/test/=' myfile
Вывод номеров строк, соответствующих шаблону
Чтение данных для вставки из файла
Выше мы рассматривали приёмы вставки данных в поток, указывая то, что надо вставить, прямо при вызове sed. В качестве источника данных можно воспользоваться и файлом. Для этого служит команда r
, которая позволяет вставлять в поток данные из указанного файла. При её вызове можно указать номер строки, после которой надо вставить содержимое файла, или шаблон.
Рассмотрим пример:
$ sed '3r newfile' myfile
Вставка в поток содержимого файла
Тут содержимое файла newfile
было вставлено после третьей строки файла myfile
.
Вот что произойдёт, если применить при вызове команды r
шаблон:
$ sed '/test/r newfile' myfile
Использование шаблона при вызове команды r
Содержимое файла будет вставлено после каждой строки, соответствующей шаблону.
Пример
Представим себе такую задачу. Есть файл, в котором имеется некая последовательность символов, сама по себе бессмысленная, которую надо заменить на данные, взятые из другого файла. А именно, пусть это будет файл newfile
, в котором роль указателя места заполнения играет последовательность символов DATA
. Данные, которые нужно подставить вместо DATA
, хранятся в файле data
.
Решить эту задачу можно, воспользовавшись командами r
и d
потокового редактора sed:
$ Sed '/DATA>/ {
r newfile
d}' myfile
Замена указателя места заполнения на реальные данные
Как видите, вместо заполнителя DATA
sed добавил в выходной поток две строки из файла data
.
Итоги
Сегодня мы рассмотрели основы работы с потоковым редактором sed. На самом деле, sed — это огромнейшая тема. Его изучение вполне можно сравнить с изучением нового языка программирования, однако, поняв основы, вы сможете освоить sed на любом необходимом вам уровне. В результате ваши возможности по обработке с его помощью текстов будет ограничивать лишь воображение.
На сегодня это всё. В следующий раз поговорим о языке обработки данных awk.
Уважаемые читатели! А вы пользуетесь sed в повседневной работе? Если да — поделитесь пожалуйста опытом.
1. Replacing all occurrences of one string with another in all files in the current directory:
These are for cases where you know that the directory contains only regular files and that you want to process all non-hidden files. If that is not the case, use the approaches in 2.
All sed
solutions in this answer assume GNU sed
. If using FreeBSD or macOS, replace -i
with -i ''
. Also note that the use of the -i
switch with any version of sed
has certain filesystem security implications and is inadvisable in any script which you plan to distribute in any way.
-
Non recursive, files in this directory only:
sed -i -- 's/foo/bar/g' * perl -i -pe 's/foo/bar/g' ./*
(the perl
one will fail for file names ending in |
or space)).
-
Recursive, regular files (including hidden ones) in this and all subdirectories
find . -type f -exec sed -i 's/foo/bar/g' {} +
If you are using zsh:
sed -i -- 's/foo/bar/g' **/*(D.)
(may fail if the list is too big, see
zargs
to work around).Bash can’t check directly for regular files, a loop is needed (braces avoid setting the options globally):
( shopt -s globstar dotglob; for file in **; do if [[ -f $file ]] && [[ -w $file ]]; then sed -i -- 's/foo/bar/g' "$file" fi done )
The files are selected when they are actual files (-f) and they are writable (-w).
2. Replace only if the file name matches another string / has a specific extension / is of a certain type etc:
-
Non-recursive, files in this directory only:
sed -i -- 's/foo/bar/g' *baz* ## all files whose name contains baz sed -i -- 's/foo/bar/g' *.baz ## files ending in .baz
-
Recursive, regular files in this and all subdirectories
find . -type f -name "*baz*" -exec sed -i 's/foo/bar/g' {} +
If you are using bash (braces avoid setting the options globally):
( shopt -s globstar dotglob sed -i -- 's/foo/bar/g' **baz* sed -i -- 's/foo/bar/g' **.baz )
If you are using zsh:
sed -i -- 's/foo/bar/g' **/*baz*(D.) sed -i -- 's/foo/bar/g' **/*.baz(D.)
The --
serves to tell sed
that no more flags will be given in the command line. This is useful to protect against file names starting with -
.
-
If a file is of a certain type, for example, executable (see
man find
for more options):find . -type f -executable -exec sed -i 's/foo/bar/g' {} +
zsh
:
sed -i -- 's/foo/bar/g' **/*(D*)
3. Replace only if the string is found in a certain context
-
Replace
foo
withbar
only if there is abaz
later on the same line:sed -i 's/foo(.*baz)/bar1/' file
In sed
, using ( )
saves whatever is in the parentheses and you can then access it with 1
. There are many variations of this theme, to learn more about such regular expressions, see here.
-
Replace
foo
withbar
only iffoo
is found on the 3d column (field) of the input file (assuming whitespace-separated fields):gawk -i inplace '{gsub(/foo/,"baz",$3); print}' file
(needs gawk
4.1.0 or newer).
-
For a different field just use
$N
whereN
is the number of the field of interest. For a different field separator (:
in this example) use:gawk -i inplace -F':' '{gsub(/foo/,"baz",$3);print}' file
Another solution using perl
:
perl -i -ane '$F[2]=~s/foo/baz/g; $" = " "; print "@Fn"' foo
NOTE: both the awk
and perl
solutions will affect spacing in the file (remove the leading and trailing blanks, and convert sequences of blanks to one space character in those lines that match). For a different field, use $F[N-1]
where N
is the field number you want and for a different field separator use (the $"=":"
sets the output field separator to :
):
perl -i -F':' -ane '$F[2]=~s/foo/baz/g; $"=":";print "@F"' foo
-
Replace
foo
withbar
only on the 4th line:sed -i '4s/foo/bar/g' file gawk -i inplace 'NR==4{gsub(/foo/,"baz")};1' file perl -i -pe 's/foo/bar/g if $.==4' file
4. Multiple replace operations: replace with different strings
-
You can combine
sed
commands:sed -i 's/foo/bar/g; s/baz/zab/g; s/Alice/Joan/g' file
Be aware that order matters (sed 's/foo/bar/g; s/bar/baz/g'
will substitute foo
with baz
).
-
or Perl commands
perl -i -pe 's/foo/bar/g; s/baz/zab/g; s/Alice/Joan/g' file
-
If you have a large number of patterns, it is easier to save your patterns and their replacements in a
sed
script file:#! /usr/bin/sed -f s/foo/bar/g s/baz/zab/g
-
Or, if you have too many pattern pairs for the above to be feasible, you can read pattern pairs from a file (two space separated patterns, $pattern and $replacement, per line):
while read -r pattern replacement; do sed -i "s/$pattern/$replacement/" file done < patterns.txt
-
That will be quite slow for long lists of patterns and large data files so you might want to read the patterns and create a
sed
script from them instead. The following assumes a <<!>space<!>> delimiter separates a list of MATCH<<!>space<!>>REPLACE pairs occurring one-per-line in the filepatterns.txt
:sed 's| *([^ ]*) *([^ ]*).*|s/1/2/g|' <patterns.txt | sed -f- ./editfile >outfile
The above format is largely arbitrary and, for example, doesn’t allow for a <<!>space<!>> in either of MATCH or REPLACE. The method is very general though: basically, if you can create an output stream which looks like a sed
script, then you can source that stream as a sed
script by specifying sed
‘s script file as -
stdin.
-
You can combine and concatenate multiple scripts in similar fashion:
SOME_PIPELINE | sed -e'#some expression script' -f./script_file -f- -e'#more inline expressions' ./actual_edit_file >./outfile
A POSIX sed
will concatenate all scripts into one in the order they appear on the command-line. None of these need end in a n
ewline.
-
grep
can work the same way:sed -e'#generate a pattern list' <in | grep -f- ./grepped_file
-
When working with fixed-strings as patterns, it is good practice to escape regular expression metacharacters. You can do this rather easily:
sed 's/[]$&^*./[]/\&/g s| *([^ ]*) *([^ ]*).*|s/1/2/g| ' <patterns.txt | sed -f- ./editfile >outfile
5. Multiple replace operations: replace multiple patterns with the same string
-
Replace any of
foo
,bar
orbaz
withfoobar
sed -Ei 's/foo|bar|baz/foobar/g' file
-
or
perl -i -pe 's/foo|bar|baz/foobar/g' file
6. Replace File paths in multiple files
Another use case of using different delimiter:
sed -i 's|path/to/foo|path/to/bar|g' *
Improve Article
Save Article
Like Article
Improve Article
Save Article
Like Article
SED command in UNIX stands for stream editor and it can perform lots of functions on file like searching, find and replace, insertion or deletion. Though most common use of SED command in UNIX is for substitution or for find and replace. By using SED you can edit files even without opening them, which is much quicker way to find and replace something in file, than first opening that file in VI Editor and then changing it.
- SED is a powerful text stream editor. Can do insertion, deletion, search and replace(substitution).
- SED command in unix supports regular expression which allows it perform complex pattern matching.
Syntax:
sed OPTIONS... [SCRIPT] [INPUTFILE...]
Example:
Consider the below text file as an input.
$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.
Sample Commands
- Replacing or substituting string : Sed command is mostly used to replace the text in a file. The below simple sed command replaces the word “unix” with “linux” in the file.
$sed 's/unix/linux/' geekfile.txt
Output :
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.
Here the “s” specifies the substitution operation. The “/” are delimiters. The “unix” is the search pattern and the “linux” is the replacement string.
By default, the sed command replaces the first occurrence of the pattern in each line and it won’t replace the second, third…occurrence in the line.
- Replacing the nth occurrence of a pattern in a line : Use the /1, /2 etc flags to replace the first, second occurrence of a pattern in a line. The below command replaces the second occurrence of the word “unix” with “linux” in a line.
$sed 's/unix/linux/2' geekfile.txt
Output:
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.
- Replacing all the occurrence of the pattern in a line : The substitute flag /g (global replacement) specifies the sed command to replace all the occurrences of the string in the line.
$sed 's/unix/linux/g' geekfile.txt
Output :
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.
- Replacing from nth occurrence to all occurrences in a line : Use the combination of /1, /2 etc and /g to replace all the patterns from the nth occurrence of a pattern in a line. The following sed command replaces the third, fourth, fifth… “unix” word with “linux” word in a line.
$sed 's/unix/linux/3g' geekfile.txt
Output:
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.
- Parenthesize first character of each word : This sed example prints the first character of every word in parenthesis.
$ echo "Welcome To The Geek Stuff" | sed 's/(b[A-Z])/(1)/g'
Output:
(W)elcome (T)o (T)he (G)eek (S)tuff
- Replacing string on a specific line number : You can restrict the sed command to replace the string on a specific line number. An example is
$sed '3 s/unix/linux/' geekfile.txt
Output:
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.
The above sed command replaces the string only on the third line.
- Duplicating the replaced line with /p flag : The /p print flag prints the replaced line twice on the terminal. If a line does not have the search pattern and is not replaced, then the /p prints that line only once.
$sed 's/unix/linux/p' geekfile.txt
Output:
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.
- Printing only the replaced lines : Use the -n option along with the /p print flag to display only the replaced lines. Here the -n option suppresses the duplicate rows generated by the /p flag and prints the replaced lines only one time.
$sed -n 's/unix/linux/p' geekfile.txt
Output:
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.
If you use -n alone without /p, then the sed does not print anything.
- Replacing string on a range of lines : You can specify a range of line numbers to the sed command for replacing a string.
$sed '1,3 s/unix/linux/' geekfile.txt
Output:
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.
Here the sed command replaces the lines with range from 1 to 3. Another example is
$sed '2,$ s/unix/linux/' geekfile.txt
Output:
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
Here $ indicates the last line in the file. So the sed command replaces the text from second line to last line in the file.
- Deleting lines from a particular file : SED command can also be used for deleting lines from a particular file. SED command is used for performing deletion operation without even opening the file
Examples:
1. To Delete a particular line say n in this exampleSyntax: $ sed 'nd' filename.txt Example: $ sed '5d' filename.txt
2. To Delete a last line
Syntax: $ sed '$d' filename.txt
3. To Delete line from range x to y
Syntax: $ sed 'x,yd' filename.txt Example: $ sed '3,6d' filename.txt
4. To Delete from nth to last line
Syntax: $ sed 'nth,$d' filename.txt Example: $ sed '12,$d' filename.txt
5. To Delete pattern matching line
Syntax: $ sed '/pattern/d' filename.txt Example: $ sed '/abc/d' filename.txt
SED command in Linux | Set 2
This article is contributed by Akshay Rajput and Mohak Agrawal. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Like Article
Save Article
If you manage to take a deeper glimpse inside the ecosystem of the Linux operating system environment, you will discover that its built-in commands are sufficient enough to solve most of our computing problems.
One such problem is the need to find and replace text, word, or string in a file especially when you are in a server environment. A solution to this problem lets you handle nagging issues like updating the “/etc/apt/sources.list” file after a successful Linux system upgrade.
Creating the Test Text File in Linux
Create a text file with a name like “test.txt” and populate it with some text, word, or string characters. Let this file be on the same path as your terminal instance.
$ nano test.txt OR $ vi test.txt
We will be using the cat command to flexible note the changes on our created test file.
$ cat test.txt
Using Sed to Find and Replace Text, Word, or String in a File
The power of this stream editor is in its easiness in accomplishing basic input streams transformation. The sed command offers a quick, easy, and timeless approach in finding and replacing targeted text, words, or string patterns in a file.
Find and Replace the First Occurrences of Text, Word, or String in File
From our created test file, we are going to update all the instances of the word “LinuxShellTips” with the alternative “this site”. The syntax of the sed command we will be using to accomplish this simple task is as follows:
$ sed -i 's/[THE_OLD_TERM]/[THE_NEW_TERM]/' [TARGETED_FILE]
With reference to the above sed command usage and syntax, we can replace our test file’s “LinuxShellTips” term with “this site” term as follows:
$ sed -i 's/LinuxShellTips/this site/' test.txt
We can now use the cat command to preview the above-proposed changes to our test file to note if any substantial edits took place.
$ cat test.txt
As you can see, the first two occurrences of the word “LinuxShellTips” have been replaced with the phrase “this site”.
Find and Replace All Occurrences of Text, Word, or String in File
Despite the above command having replaced all the targeted word patterns in our test file, its usage tends to be selective in most circumstances. The command works best for small files because, in big files, only the first few occurrences of a targeted word pattern might benefit from its ‘find and replace’ prowess.
To find and replace all occurrences of a word pattern in any editable file, you should adhere to the following sed command syntax.
$ sed -i 's/[THE_OLD_TERM]/[THE_NEW_TERM]/g' [TARGETED_FILE]
As you have noted, the 'g'
in the above find & replace command syntax acts as a global variable so that all the global occurrences of a term in a targeted file are considered.
$ sed -i 's/this site/LinuxShellTips/g' test.txt
The above command finds all the global occurrences of the term “this site” and replaces it with the term “LinuxShellTips”.
Using Awk to Find and Replace Text, Word, or String in File
If you are familiar with the awk command-line utility, then you know that its powerful scripting language metrics make it a pro at text processing. Linux system administrators and professional users find this tool effective in data extraction and reporting.
The awk command syntax for a simple find-and-replace operation looks like the following snippet:
$ awk '{gsub("[THE_OLD_TERM]","[THE_NEW_TERM]"); print}' [TARGETED_FILE]
In the above syntax, awk will substitute THE_OLD_TERM from THE_NEW_TERM in the TARGETED_FILE and print the resulting file content on the system terminal.
Let us take a practical approach:
$ awk '{gsub("Linux","ubuntu"); print}' test.txt
With the dynamic functionalities of both sed and awk command tools, you should now find, replace, and overwrite text, word, or string patterns in a targeted file. These tools give a system user the needed flexibility while on a command-line interface.