admin / 07.08.2018
Утилита sed это мощный потоковый редактор текста с поддержкой регулярных выражений. С помощью sed вы можете заменять шаблоны текста (причем непосредственно в файле!), удалять строки (элементы массива), выводить подходящие по маске строки (подобно grep). Редактор sed поддерживает применение нескольких команд и расширенный синтаксис регулярных выражений (при котором не нужно экранировать спец. символы).
Содержание
В sed нет поддержки опережающих и ретроспективных проверок в регулярках! Для замены с использованием расширенного синтаксиса regex используйте:
В довольно проблемно работать с символом перевода строки! Самое удобное решение — это:
Шаблон:
В качестве разделителей можно использовать любые символы (напрмиер: , ). Match части (которые внутри круглых скобок) доступны как , , .
Опции утилиты:
Флаги строки-команды (указывать в конце маски):
Вывести строки 1-5:
Вывести файлы соответствующие маске:
Строки длиннее 80 символов:
Вывести вхождения (matches) через табуляцию:
Заменить названия файлов (composer на composer-dev):
Заменить символы (regex):
Заменить URL в файле (штука в разделителях , и для замены в файле):
Заменить параметр в конфиге:
Удалить начальные пробелы (аналог ltrim):
Удалить из файла строку подходящую шаблону:
Удалить первую строку вывода:
Удалить строки от первой до соответствующей regex:
Заменить подстроку:
По умолчанию необходимо экранировать все спец. символы в regex’ах, что крайне затрудняет чтение масок. Для того, чтобы экранировать спец.символы только в случае описания в тексте их самих — включите расширенный режим regex выражений с помощью опции .
Удалить пустые строки:
Удалить последние N=2 символа:
Вырезать / запомнить последние N=4 символа:
#sed, #regexp, #bash
категория: Bash
Sed — лёгкий (бинарник весит всего 128 килобайт) и удобный инструмент обработки текста.
В этой статье я приведу несколько простых примеров использования sed и расскажу о его основных возможностях.
Sed получает входной поток данных или файл построчно, редактирует каждую строку согласно правилам, определённым в sed-скрипте, и затем выводит результат. Sed это тьюринг-полный язык программирования.
Команда sed имеет формат:
Флаг -n подавляет вывод
-e — указывает на список инструкций, заданный в командной строке.
-f — указывает местонахождение файла-скрипта.
Скриптовый файл состоит из набора команд:
по одной в каждой строке.
Адреса это либо номера строк, либо специальные символы, либо регулярное выражение:
$ — последняя строка
начало~N — Каждая N-я строка, начиная с номера начало
/регулярное_выражение/ — строки, попадающие под регулярное_выражение
Примеры:
Рассмотрим основные команды:
[адрес] a текст — добавить новую строку с текстом после указанной строки
[адрес [, адрес]] c текст — Удаляет выбранные строки и заменяет их на текст
[адрес [, адрес]] d — Удаляет указанные строки.
[адрес] i текст — Вставить текст на место указанной строки.
[адрес [, адрес]] p (с флагом -n) выводит найденные строки.
[адрес] q — выход из sed.
[адрес [, адрес]] r файл — Читает файл и выдает его содержание на выход.
[адрес [, адрес]] s/регулярное_выражение/замена/флаги — Заменяет регулярное_выражение на замена-у с учётом флагов:
[адрес [, адрес]] y/строка1/строка2/ — Заменяет все вхождения символов в строке1 соответсвующими символами из строки2.
Длины строк должны быть одинаковыми.
[адрес [, адрес]] { команды } — скобки группируют команды
[адрес] = — Выдаёт номера строк
: метка — сопоставить группе команд метку
b метка — переход к команде, обозначенной меткой метка, если метка отсутствует, то переход в конец командного файла.
t метка — переход к команде, обозначенной меткой метка только после удачной замены с помощью команды s///
sed работает с двумя буферами данных: основным и вспомогательным. Изначально оба буфера пусты.
Работа с этими буферами осуществляется при помощи команд:\\`h’, `H’, `x’, `g’, `G’ `D’ h — Заменить содержимое вспомогательного буфера содержимым основного
H — Добавить новую строку к вспомогательному буферу и затем добавить содержимое основного буфера к содержимому вспомогательного
x — Поменять содержимое обоих буферов местами
g — Заменить содержимое основного буфера содержимым вспомогательного
G — Добавить новую строку к основному буферу и затем добавить содержимое вспомогательного буфера к содержимому основного
D — Удалить текст основного буфера до следующего символа перевода строки
N — Добавить новую строку к основному буферу, затем добавить туда следующую обрабатываемую строку
P — Вывести содержимое основного буфера до следующего символа перевода строки.
Следующий скрипт меняет местами строки файла (первые строки становятся последними и наоборот)
Считаем строки файла (выводим номер последней строки)
результат
Обращение строк
Этот скрипт перемещает две буквы за раз.
Подробнее о формате sed-скриптов можно узнать, прочитав мануал man sed или техническую документацию info sed.
02.02.2013
(Использовались материалы [ 1] [ 2] и [ 3])
Для работы над строками средствами Bash используются параметры разложения (parameter expansions) Описание этого принципа можно найти в в пункте .
Описание трудновато для понимания. Намного проще понять принцип работы на примерах.
Любой одиночный символ обозначается как
Зададим переменную
[shonty@~]$ STRING=aabbcc [shonty@~]$ echo ${STRING} aabbcc Для удаления символов в начале строки используем команды: [shonty@~]$ echo ${STRING#?} abbcc [shonty@~]$ echo ${STRING#???} bcc для удаления символов в конце строки: [shonty@~]$ echo ${STRING%?} aabbc [shonty@~]$ echo ${STRING%???} aab Что бы запомнить, когда применять знак , а когда используют вот такой оригинальный способ:
Символы располагаются на клавиатуре последовательно и:
— слева от , означает с начала строки
— справа от , означает до конца строки
Регулярные выражения (regular expressions или RegExp, regex) — это строка-шаблоном или «маска» задающая правило поиска.
Снова зададим переменную
[shonty@~]$ STRING=GNULinux [shonty@~]$ echo ${STRING} GNULinux удаляем регулярное выражение в начале строки: [shonty@~]$ echo ${STRING#GNU} Linux удаляем регулярное выражение в конце строки: [shonty@~]$ echo ${STRING%Linux} GNU Теперь тоже самое, но используя «*» (астериск)
удаляем регулярное выражение в начале строки (): [shonty@~]$ echo ${STRING#*U} Linux удаляем регулярное выражение в конце строки (): [shonty@~]$ echo ${STRING%L*} GNU
Использование регулярных выражений может быть скомбинировано с «?» (знаком любого символа) ():
[shonty@~]$ echo ${STRING%??n*} GNU
Если при удалении из строки регулярных выражений (*regex или regex*), при использовании «#» и «%» с «*» — удаление идёт до первого вхождения регулярного выражения, то при использовании сдвоенных «##» и «%%» — до последнего:
И снова зададим переменную
[shonty@~]$ STRING=abcdcba [shonty@~]$ echo ${STRING} abcdcba STRING=abcdcba ${STRING#*c} dcba ${STRING##*c} ba ${STRING%c*} abcd ${STRING%%c*} ab[shonty@~]$ echo ${STRING#*c} dcba [shonty@~]$ echo ${STRING##*c} ba [shonty@~]$ echo ${STRING%c*} abcd [shonty@~]$ echo ${STRING%%c*} ab
Поиск и замена
-замена первого вхождения
-глобальная замена
[shonty@~]$ STRING=»abracadabra» [shonty@~]$ echo «${STRING/a/O}» Obracadabra [shonty@~]$ echo «${STRING//a/O}» ObrOcOdObrO [shonty@~]$ echo «${STRING/#a/O}» Obracadabra [shonty@~]$ echo «${STRING/%a/O}» abracadabrO [shonty@~]$ echo «${STRING/a/}» bracadabra [shonty@~]$ echo «${STRING//a/}» brcdbr
-смещение от края строки
-длина подстроки
5.1 Смещение при положительных значениях
При положительных значениях смещения первому символу строки соответствует значение «».
Если не задана, то длина подстроки автоматически продляется до конца.
Примеры с положительными значениями : [shonty@~]$ STRING=»Debian Gentoo RedHat» [shonty@~]$ echo ${STRING:0:6} Debian [shonty@~]$ echo ${STRING:14} RedHat [shonty@~]$ echo ${STRING:7:6} Gentoo
5.2 Смещение при отрицательных значениях
При отрицательных значениях отсчёт ведётся от конца строки, а последнему символу строки соответствует значение равное «».
Для записи отрицательного смещения между двоеточием и знаком минус нужно оставлять пробел или брать отрицательное значение в круглые скобки.
Если не задана, то длина подстроки автоматически продляется до конца.
Примеры с отрицательными значениями : [shonty@~]$ STRING=»Debian Gentoo RedHat» [shonty@~]$ echo ${STRING: -6} RedHat [shonty@~]$ echo ${STRING:(-6)} RedHat [shonty@~]$ echo ${STRING:(-6):3} Red [shonty@~]$ echo ${STRING:(-6):10} # длина превышает смещение RedHat
5.3 Отрицательные значения .
Если принимает отрицательное значение, то она работает как смещение от конца строки. Результатом будет подстрока между первым и вторым смещениями:
[shonty@~]$ STRING=»Debian Gentoo RedHat» [shonty@~]$ echo ${STRING:7:-7} Gentoo [shonty@~]$ echo ${STRING:(-14):-7} Gentoo
Ниже представлены различные варианты кода для смены расширения с на при пакетном перекодировании аудио файлов: for i in *.wav; do lame «$i» «${i%???}mp3»; done; for i in *.wav; do lame «$i» «${i%wav}mp3»; done; for i in *.wav; do lame «$i» «${i%.*}.mp3»; done; for i in *.wav; do lame «$i» «${i/wav/mp3}»; done; for i in *.wav; do lame «$i» «${i:0:-3}mp3»; done;
[shonty@~]$ STRING=»Подсчёт количества символов в строке» [shonty@~]$ echo ${#STRING} 36
Узнать количество символов в файле: [shonty@~]$ ARRAY=(`cat file.html`) [shonty@~]$ echo ${#ARRAY[@]} 1158
Здесь нужно отметить, что файл читается не просто в переменную, а в массив, так как он состоит из нескольких строк. Поэтому для правильного подсчёта необходимо ставить . Если этого не сделать, то команда прочитает только первую строку из файла:
[shonty@~]$ ARRAY=(`cat file.html`) [shonty@~]$ echo ${#ARRAY} 7 И правда, первая строка содержит лишь тег и символ перевода строки виндовс () — и того 7 символов.
-переводит первый символ в верхний регистр
-переводит все символы в верхний регистр
-переводит первый символ в нижний регистр
-переводит все символы в нижний регистр
-инвертирует регистр первого символа
-инвертирует регистр всех символов
Теги: Linux, bash, shell, regular expressions, parameter expansions, RegExp, regex, length, offset, for, in, do. lame, done, *.wav, mp3, CR+LF, регулярные выражения, шаблон, поиск, переменная, массив, строка, символы, верхний, нижний, регистр
Вернуться к оглавлению
http://onedev.net/post/267
Утилита sed это мощный потоковый редактор текста с поддержкой регулярных выражений. С помощью sed вы можете заменять шаблоны текста (причем непосредственно в файле!), удалять строки (элементы массива), выводить подходящие по маске строки (подобно grep). Редакторsed поддерживает применение нескольких команд и расширенный синтаксис регулярных выражений (при котором не нужно экранировать спец. символы).
В довольно проблемно работать с символом перевода строки!
Самое удобное решение – это:
Шаблон:
В качестве разделителей можно использовать любые символы (напрмиер: , ). Match части (которые внутри круглых скобок) доступны как , , .
Опции:
Флаги:
Вывести строки 1-5:
Вывести файлы соответствующие маске:
Строки длиннее 80 символов:
Вывести вхождения (matches) через табуляцию:
Заменить названия файлов (composer на composer-dev):
Заменить символы (regex):
Заменить URL в файле (штука в разделителях , и для замены в файле):
Удалить начальные пробелы (аналог ltrim):
Удалить первую строку вывода:
Удалить строки от первой до соответствующей regex:
Заменить подстроку:
По умолчанию необходимо экранировать все спец.
символы в regex’ах, что крайне затрудняет чтение масок. Для того, чтобы экранировать спец.символы только в случае описания в тексте их самих – включите расширенный режим regex выражений с помощью опции .
Удалить пустые строки:
Удалить последние N=2 символа:
Вырезать / запомнить последние N=4 символа:
#sed, #regexp, #bash
Используйте , но пусть оболочка выполнит математику, с целью использовать команду , указав диапазон (чтобы удалить последние 23 строки):
Чтобы удалить последние 3 строки, изнутри:
Дает количество строк файла: скажем, 2196
Мы хотим удалить последние 23 строки, поэтому для левой или диапазона:
Дает: 2714 Таким образом, первоначальный sed после интерпретации оболочки:
С делает редактирование на месте, теперь файл имеет 2173 строк!
Я придумал это, где n — количество строк, которые вы хотите удалить:
Это немного круговое движение, но я думаю, что легко следовать.
Попробуйте выполнить следующую команду:
Если hardcoding n является опцией, вы можете использовать последовательные вызовы sed. Например, чтобы удалить последние три строки, удалите последнюю одну строку трижды:
Это можно сделать в 3 этапа:
a) Подсчитайте количество строк в файле, который вы хотите изменить:
б) Вычесть из этого числа количество строк для удаления:
c) Сообщите sed удалить из этого номера строки ( ) до конца:
Для полноты я хотел бы добавить свое решение. Я закончил это со стандартным :
Это удаляет последние 2 строки, используя редактирование на месте (хотя он использует временный файл в !!)
posix версия
С ответами здесь вы уже узнали бы, что sed — не лучший инструмент для этого приложения.
Однако я думаю, что есть способ сделать это при использовании sed; идея состоит в том, чтобы добавить N строк для удержания пространства, пока вы не сможете читать, не нажимая EOF.
Когда EOF попал, распечатайте содержимое пространства удержания и закройте.
Команда sed выше будет опускать последние 5 строк.
Итак, у меня проблема, когда эта часть моего script не работает. Я не уверен, что происходит, но я чувствую это, потому что я не избежал определенных символов внутри переменных. Я попробовал следующее без везения:
Вот что в каждой из переменных:
Переменная CTMP — это всего лишь строка из файла crontab
Переменная — это время в минутах установки файла cron
Переменная DIR — это текущий рабочий каталог
И переменная script — это просто имя файла script
Я чувствую, что проблема заключается в том, что инструкция sed не обновляет файл crontab, потому что она не ускользает от символов, которые ему нужны, внутри этих переменных выше.
Это правильно или что-то еще не так?
* ОБНОВЛЕНИЕ *
* ОБНОВЛЕНИЕ *
Вот вывод crontab
и я также повторил три экранированные переменные только для устранения неполадок, и вот они:
Три экранированные переменные действительно выглядят хорошо.
* ОБНОВЛЕНИЕ *
Файл Cron перед заменой:
Файл Cron после замены:
Посмотрите все лишние барахлы, которые попадают туда как-то?
bashsed
задан Atomiklan 24 июня '13 в 13:12
источникподелиться
FILED UNDER : IT