- Linux sed несколько условий
- Основные команды Sed
- Удалить что-то из файла
- Сделать замену
- Экранирование символов в sed
- Два условия одновременно в Sed
- Получить диапазон строк
- Заменить всё между определёнными символами
- Создать функцию
- Отбросить всё, что левее определённого слова
- Отбросить всё, что правее определённого слова
- Удаление переходов на новую строку
- Удалить всё после определённой строки
- Linux sed несколько условий
- Основные команды Sed
- Удалить что-то из файла
- Сделать замену
- Экранирование символов в sed
- Два условия одновременно в Sed
- Получить диапазон строк
- Заменить всё между определёнными символами
- Создать функцию
- Отбросить всё, что левее определённого слова
- Отбросить всё, что правее определённого слова
- Удаление переходов на новую строку
- Удалить всё после определённой строки
Linux sed несколько условий
Вам могут пригодится также статьи AWK и GREP
Примеры я показываю в Bash под Windows 10 или в Bash в Linux .
Основные команды Sed
Для того чтобы применить SED достаточно ввести в командную строку
echo ice | sed s / ice / fire /
Обратите внимание на то, что использовать / не обязательно.
Вы можете после s поставить какой-то другой символ, например : или , или |
Результат будет тем же, главное, чтобы все три разделителя были одинаковыми и сам символ был без дополнительных смыслов.
echo mice | sed s / m / r /
echo mice | sed s , m , r ,
echo mice | sed s : m : r :
Если вы выбрали |, то команду нужно взять в кавычки — у | есть особая роль в bash — pipeline
Если вы редактируете пути до файлов (а они содержат /) то это как раз тот случай, когда удобно выбрать другой разделитель
Например, нужно заменить /bin/bash на /bin/sh
Намного удобнее использовать @ как разделитель чем экранировать каждый слеш.
Сравните две идентичные команды
sed ‘s @ /bin/bash @ /bin/sh @ ‘ /etc/passwd
sed ‘s / \ /bin \ /bash / \ /bin \ /sh / ‘ /etc/passwd
Удалить что-то из файла
За удаление отвечает опция d про неё вы можете прочитать отдельную статью sed d
Также можно удалять заменой на пустое место
И удалять с помощью других опций, например, q
Сделать замену
За замену отвечает опция s про неё вы можете прочитать отдельную статью sed s — substitute
Экранирование символов в sed
Специальные символы экранируются с помощью \
Что включать в специальные символы зависит от того, какой sed вы используете, но $.*[\^ а также пробелы и кавычки советую экранировать всегда.
Пробел также можно заменять на \s
. в регулярных выражениях обозначает один любой символ кроме начала новой строки \n поэтому, если вы хотите написать url используйте \
Пример экранирования точек и кавычек для смены локали в CentOS можете изучить здесь
Предположим, что есть файл 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, и записать в файл.
В результате получим ошибку
-e expression #1, char 15: unknown option to `s’
Чтобы команда заработала нужно добавить \ перед /
Here is a String Here is an Integer Here is a Float
Экранирование пробелов может пригодиться при замене одной фразы на другую
Чтобы в скрипте sites.sh из директории /opt/andrei/scripts/ заменить фразу Bike website topbicycle.ru на Travel website heihei.ru нужно выполнить
sed -i s/Bike \ website \ topbicycle.ru/Travel \ website \ heihei.ru/ /opt/andrei/scripts/sites.sh
Два условия одновременно в 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
Получить диапазон строк
В случае, когда Вы работаете с большими файлами, например с логами, часто бывает нужно получить только определённые строки, например, в момент появления бага.
Копировать из UI командной строки не всегда удобно, но если Вы примерно представляете диапазон нужных строк — можно скопировать только их и записать в отдельный файл.
Например, Вам нужны строки с 9570 по 9721
sed -n ‘9570,9721p;9722q’ project-2019-10-03.log > bugFound.txt
Заменить всё между определёнными символами
Удалить всё что находится между квадратными скобками включая скобки
sed ‘s/\[.*\]//’ input.txt > output.txt
Создать функцию
Чтобы каждый раз не вспоминать команды sed можно создать функцию
Возьмём команду, которая удаляет комментарии и пустые строки из предыдущего примера и запишем как функцию clean_file.
Первым делом в коносли нужно написать в терминале function clean_file < и нажать Enter
Затем ввести выражение sed -i ‘/^#/d ; /^$/d’ $1
$1 означает, что функция будет принимать один аргумент. Это, конечно, будет название файла.
Затем нужно снова нажать Enter и в новой строке написать > и нажать Enter ещё раз
$ function clean_file < >sed -i ‘/^#/d;/^$/d’ $1 > >
Убедитесь, что файл содержит комментарии и пустые строки. Если нет — создайте для чистоты эксперимента.
clean_file websites
cat websites
Отбросить всё, что левее определённого слова
Предположим, что у нас есть файл 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
^ означает, что мы стартуем с начала строки Результат:
Для доступности объясню синтаксис сравнив две команды. Посмотрите внимательно, когда мы заменяем слово 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 3q input.txt > output.txt
Linux sed несколько условий
Вам могут пригодится также статьи AWK и GREP
Примеры я показываю в Bash под Windows 10 или в Bash в Linux .
Основные команды Sed
Для того чтобы применить SED достаточно ввести в командную строку
echo ice | sed s / ice / fire /
Обратите внимание на то, что использовать / не обязательно.
Вы можете после s поставить какой-то другой символ, например : или , или |
Результат будет тем же, главное, чтобы все три разделителя были одинаковыми и сам символ был без дополнительных смыслов.
echo mice | sed s / m / r /
echo mice | sed s , m , r ,
echo mice | sed s : m : r :
Если вы выбрали |, то команду нужно взять в кавычки — у | есть особая роль в bash — pipeline
Если вы редактируете пути до файлов (а они содержат /) то это как раз тот случай, когда удобно выбрать другой разделитель
Например, нужно заменить /bin/bash на /bin/sh
Намного удобнее использовать @ как разделитель чем экранировать каждый слеш.
Сравните две идентичные команды
sed ‘s @ /bin/bash @ /bin/sh @ ‘ /etc/passwd
sed ‘s / \ /bin \ /bash / \ /bin \ /sh / ‘ /etc/passwd
Удалить что-то из файла
За удаление отвечает опция d про неё вы можете прочитать отдельную статью sed d
Также можно удалять заменой на пустое место
И удалять с помощью других опций, например, q
Сделать замену
За замену отвечает опция s про неё вы можете прочитать отдельную статью sed s — substitute
Экранирование символов в sed
Специальные символы экранируются с помощью \
Что включать в специальные символы зависит от того, какой sed вы используете, но $.*[\^ а также пробелы и кавычки советую экранировать всегда.
Пробел также можно заменять на \s
. в регулярных выражениях обозначает один любой символ кроме начала новой строки \n поэтому, если вы хотите написать url используйте \
Пример экранирования точек и кавычек для смены локали в CentOS можете изучить здесь
Предположим, что есть файл 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, и записать в файл.
В результате получим ошибку
-e expression #1, char 15: unknown option to `s’
Чтобы команда заработала нужно добавить \ перед /
Here is a String Here is an Integer Here is a Float
Экранирование пробелов может пригодиться при замене одной фразы на другую
Чтобы в скрипте sites.sh из директории /opt/andrei/scripts/ заменить фразу Bike website topbicycle.ru на Travel website heihei.ru нужно выполнить
sed -i s/Bike \ website \ topbicycle.ru/Travel \ website \ heihei.ru/ /opt/andrei/scripts/sites.sh
Два условия одновременно в 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
Получить диапазон строк
В случае, когда Вы работаете с большими файлами, например с логами, часто бывает нужно получить только определённые строки, например, в момент появления бага.
Копировать из UI командной строки не всегда удобно, но если Вы примерно представляете диапазон нужных строк — можно скопировать только их и записать в отдельный файл.
Например, Вам нужны строки с 9570 по 9721
sed -n ‘9570,9721p;9722q’ project-2019-10-03.log > bugFound.txt
Заменить всё между определёнными символами
Удалить всё что находится между квадратными скобками включая скобки
sed ‘s/\[.*\]//’ input.txt > output.txt
Создать функцию
Чтобы каждый раз не вспоминать команды sed можно создать функцию
Возьмём команду, которая удаляет комментарии и пустые строки из предыдущего примера и запишем как функцию clean_file.
Первым делом в коносли нужно написать в терминале function clean_file < и нажать Enter
Затем ввести выражение sed -i ‘/^#/d ; /^$/d’ $1
$1 означает, что функция будет принимать один аргумент. Это, конечно, будет название файла.
Затем нужно снова нажать Enter и в новой строке написать > и нажать Enter ещё раз
$ function clean_file < >sed -i ‘/^#/d;/^$/d’ $1 > >
Убедитесь, что файл содержит комментарии и пустые строки. Если нет — создайте для чистоты эксперимента.
clean_file websites
cat websites
Отбросить всё, что левее определённого слова
Предположим, что у нас есть файл 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
^ означает, что мы стартуем с начала строки Результат:
Для доступности объясню синтаксис сравнив две команды. Посмотрите внимательно, когда мы заменяем слово 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 3q input.txt > output.txt