SED

Содержание статьи
Замена слова в файле
Замена слова в нескольких файлах одновременно
Отбросить всё, что слева
Отбросить всё, что справа
Экранирование символов
Два условия одновременно
Удаление переходов на новую строку
Обрезать файл - Удалить всё начиная с определённой строки
Удалить строку в которой есть определённое слово/слова
Получить диапазон строк
Удалить пустые строки
Заменить пустые строки
Удалить комментарии из кода
Создать функцию

Это статья про SED. Про AWK и GREP Вы можете прочитать в статье Текстовые препроцессоры

По умолчанию я предполагаю, что Вы работаете в Bash под Windows 10 . Как установить Bash в Windows 10 подробно описано здесь.

Основные команды Sed

Для того чтобы применить SED достаточно ввести в командную строку

echo ice | sed s/ice/fire/

Результат:

fire

Замена слова в файле

Обычно SED применяют к файлам, например к логам или конфигам.

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String Here is an Integer Here is a Float

Мы хотим заменить слово Here на There

sed 's/Here/There/' input.txt

Результат будет выведен в консоль:

There is a String

There is an Integer

There is a Float

Если нужно не вывести в консоль а изменить содержание файла - используем опцию -i

sed -i 's/Here/There/' input.txt

В этом случае перепишется исходный файл input.txt

Рассмотрим пример посложнее. Файл input.txt теперь выглядит так:

Here is an Apple. Here is a Pen. Here is an ApplePen Integer is Here Here is a Float Here is a Pen. Here is a Pineapple. Here is a PineapplePen

sed 's/Here/There/' input.txt

Как Вы сейчас увидите, замена произойдёт только по одному разу в строке

There is an Apple. Here is a Pen. Here is an ApplePen

Integer is There

There is a Float

There is a Pen. Here is a Pineapple. Here is a PineapplePen

Чтобы заменить все слова нужна опция g

sed 's/Here/There/g' input.txt

There is an Apple. There is a Pen. There is an ApplePen
Integer is There

There is a Float

There is a Pen. There is a Pineapple. There is a PineapplePen

ApplePen

Замена слова в файле и вывод результата в другой файл

Та же замена, но с выводом в новый текстовый файл, который мы назовём output:

sed 's/Here/There/' input.txt > output.txt

Замена слова в нескольких файлах одновременно

Если нужно обработать сразу несколько файлов: например файл 1.txt с содержанием

First File: Here

И файл 2.txt с содержанием

Second File: Here

Это можно сделать используя *.txt

sed 's/Here/There/' *.txt > output.txt

На выходе файл output.txt будет выглядеть так

First File: There Second File: There

Отбросить всё, что левее определённого слова

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String it has a Name Here is an Integer it has a Name Here is a Float it has a Name

Мы хотим отбросить всё, что находится левее слова it, включая слово it, и записать в файл.

sed 's/^.*it//' input.txt > output.txt

^ означает, что мы стартуем с начала строки Результат:

 has a Name

 has a Name

 has a Name

Для доступности объясню синтаксис сравнив две команды. Посмотрите внимательно, когда мы заменяем слово Here на There.

There находится между двумя слэшами. Раскрашу их для наглядности в зелёный и красный.

sed 's/Here/There/'

А когда мы хотим удалить что-то, мы сначала описываем, что мы хотим удалить. Например, всё от начала строки до слова it.

Теперь в правой части условия, где раньше была величина на замену, мы ничего не пишем, т.е. заменяем на пустое место. Надеюсь, логика понятна.

sed 's/^.*it//' > output.txt

Отбросить всё, что правее определённого слова

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String / it has a Name Here is an Integer / it has a Name Here is a Float / it has a Name

Мы хотим отбросить всё, что находится правее слова is, включая слово is, и записать в файл.

sed 's/is.*//' > output.txt

Результат:

Here Here Here

Экранирование символов в sed

Специальные символы экранируются с помощью \

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String / it has a Name Here is an Integer / it has a Name Here is a Float it / has a Name

Мы хотим отбросить всё, что находится левее /a, включая /a, и записать в файл.

sed 's/^.*/a//' > output.txt

В результате получим ошибку

-e expression #1, char 15: unknown option to `s'

Чтобы команда заработала нужно добавить \ перед /

sed 's/^.*\/a//' > output.txt

Результат:

Here is a String Here is an Integer Here is a Float

Два условия одновременно в Sed

Предположим, что у нас есть файл input.txt следующего содержания

Here is a String /b it has a Name Here is an Integer /b it has a Name Here is a Float /b it has a Name

Мы хотим отбросить всё, что находится левее /b, включая /b, и всё, что правее has.

Таким образом, в каждой строчке должно остаться только слово it.

Нужно учесть необходимость экранирования специального символа / а также мы хотим направить вывод в файл.

sed 's/^.*\/b// ; s/has.*//' input.txt > output.txt

Результат:

it it it

Удаление переходов на новую строку

sed ':a;N;$!ba;s/\n//g' file ;

Удалить всё после определённой строки

Допустим Вы хотите удалить все строки после третьей

sed 3q input.txt > output.txt

Удалить строку

Допустим Вы хотите удалить все строки где встречается слово Apple в файле input.txt

Here is an Apple Here Pen Here ApplePen Integer is Here Here is a Float Here Pen Here Pineapple Here PineapplePen Umm Apple Apple Apple Pen

Сделать это можно с помощью опции d

sed '/Apple/d' input.txt > output.txt

Результат:

Integer is Here Here is a Float Here Pen Here Pineapple Here PineapplePen

Теперь сделаем более сложное условие - удалим все строки где есть слово Pineapple и слово Integer

sed '/Pineapple\|Integer/d' input.txt > output.txt

| выступает в роли логического ИЛИ

\ нужна чтобы экранировать |

Результат:

Here is an Apple. Here is a Pen. Here is an ApplePen Here is a Float Umm Apple Apple Apple Pen

Получить диапазон строк

В случае, когда Вы работаете с большими файлами, например с логами, часто бывает нужно получить только определённые строки, например, в момент появления бага.

Копировать из UI командной строки не всегда удобно, но если Вы примерно представляете диапазон нужных строк - можно скопировать только их и записать в отдельный файл.

Например, Вам нужны строки с 9570 по 9721

sed -n '9570,9721p;9722q' project-2019-10-03.log > bugFound.txt

Удалить пустые строки

Если строка действительно пустая, то подойдёт команда

sed '/^$/d'

Обычно жизнь более жестока, и в строках содержатся пробелы.

Удалить такие строки тоже можно

$ sed '/^[[:space:]]*$/d' input.txt > output.txt

Заменить пустые строки

Заменить все пустые строки на двойные тэги переноса строки

$ sed 's/^[[:space:]]*$/\<br\>\<br\>/' input.txt > output.txt

Заменить всё между определёнными символами

Удалить всё что находится между квадратными скобками включая скобки

sed 's/\[.*\]//' input.txt > output.txt

Удалить комментарии

Допустим, у вас есть код или просто текст в котором много комментариев.

Строка с комментариями начинается с символа #

Рассмотрим файл websites

cat websites

# Travel https://www.heihei.ru # Bicycles https://www.topbicycle.ru # IT https://www.urn.su

Чтобы удалить строки с комментариями выполните

sed -i '/^#/d' websites

Опция -i позволяет изменять текущий файл

Если хотите сохранить исходный файл а текст без комментариев записать в новы (если вы уже удалили комментарии - убедитесь, что вы их вернули обратно)

sed '/^#/d' websites > nocomments
cat nocomments

https://www.heihei.ru https://www.topbicycle.ru https://www.urn.su

Опция -i не нужна так как исходный файл мы не изменяли

Чтобы удалить строки с комментариями и пустые строки выполните

sed -i '/^#/d ; /^$/d' websites

Создать функцию

Чтобы каждый раз не вспоминать команды sed можно создать функцию

Возьмём команду, которая удаляет комментарии и пустые строки из предыдущего примера и запишем как функцию clean_file.

Первым делом в коносли нужно написать в терминале function clean_file { и нажать Enter

Затем ввести выражение sed -i '/^#/d ; /^$/d' $1

$1 означает, что функция будет принимать один аргумент. Это, конечно, будет название файла.

Затем нужно снова нажать Enter и в новой строке написать } и нажать Enter ещё раз

$ function clean_file { > sed -i '/^#/d;/^$/d' $1 > }

Убедитесь, что файл содержит комментарии и пустые строки. Если нет - создайте для чистоты эксперимента.

cat websites

# Travel https://www.heihei.ru # Bicycles https://www.topbicycle.ru # IT https://www.urn.su

clean_file websites
cat websites

https://www.heihei.ru https://www.topbicycle.ru https://www.urn.su

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

Поиск по сайту

Контакты и сотрудничество:
Рекомендую наш хостинг beget.ru
Пишите на info@urn.su если Вы:
1. Хотите написать статью для нашего сайта или перевести статью на свой родной язык.
2. Хотите разместить на сайте рекламу, подходящуюю по тематике.
3. Реклама на моём сайте имеет максимальный уровень цензуры. Если Вы увидели рекламный блок недопустимый для просмотра детьми школьного возраста, вызывающий шок или вводящий в заблуждение - пожалуйста свяжитесь с нами по электронной почте
4. Нашли на сайте ошибку, неточности, баг и т.д. ... .......
5. Статьи можно расшарить в соцсетях, нажав на иконку сети: