Как стать автором
Обновить

Комментарии 9

Объясните пожалуйста др. пример:

Грубый эмулятор grep:

sed -ne "/некоесловодляпоиска/s|^|имяфайладляпоиска: |p"
sed -ne "/$1/s|^|${file}: |p"

Не могу понять что в данном примере делает знак "/s" который вроде как для замены(в данном случае возможно просто заставляет выступить $1 в качестве фильтра) и знак начала строки "^"?

/некоесловодляпоиска/ - первая конструкция, ищет по шаблону

s|^|имяфайладляпоиска: |p - вторая конструкция, меняет в найденной строке начало строки на имяфайладляпоиска: .

Т.е. это не знак /s, это конструкция s|||. В sed не обязательно использовать символ "/" в качестве разделителя s

Потому что в этой статье материал подан так, что «а вот это заклинание делает вот такую магию», потому ничего и не понятно. Лучше почитайте краткий учебник по sed и всё сразу встанет на свои места. В вашем примере общий вид команды sed такой:


<адресное выражение> <команда замены>

где <адресное выражение>/некоесловодляпоиска/, то есть регулярное выражение (идентифицируется двумя косыми чертами //), с которым должна совпасть строка, чтобы следующая за ним команда её обработала, а <команда замены>s|<что заменить>|<на что заменить>|<флаг> (разделителями команды замены s могут выступать не только косые черты, а любой другой символ, в данном случае символ вертикальной черты |). В <что заменить> указана каретка ^, то есть, начало строки (по сути — некая позиция), а в <на что заменить> — текст, который по итогу будет в начало строки добавлен. Последний символ p — это флаг команды s, указывающий ей распечатать результат замены.

Небольшое уточнение: p - это не флаг команды s, а самостоятельная команда "print".

Нет, в данном случае это именно флаг. Фрагмент из справочной страницы sed'а:


Для команды s предусмотрено множество МОДИФИКАТОРОВ:

p
  • Если РЕГУЛЯРНОЕ_ВЫРАЖЕНИЕ найдено, то происходит вывод буфера в выходной поток.

Отдельную команду p тоже, конечно, можно использовать, только тогда её, во-первых, надо будет отделить символом точка с запятой ; от команды s (в случае однострочной записи, как оно и бывает при вызове из терминала, либо расположить их на разных строках, если пишем отдельный скрипт для sed'а), а во-вторых, заключить обе команды в блок — фигурные скобки {} — потому что иначе адресное выражение будет относиться только к первой команде:


sed -ne "/некоесловодляпоиска/ { s|^|имяфайладляпоиска: |; p }"

Изучить sed несложно: поредактируйте файлы из консоли, напишите программку на любом ЯП, но используя sed в качестве редактора. По вкусу можно вместо sed использовать при этом ed. После этого команды просто автоматически будут от зубов отскакивать.

А для непосвященных - МАГИЯ, да :)
впрочем как и от vi, когда в нём умеешь работать (с буферами copy-paste и прочим), когда в деталях знаешь нюансы отличий команд vim (который под Linux обычно ставят как vi) от nvi (который ставится по умолчанию во FreeBSD)...

3. Удалить строки с x по y:

Синтаксис: sed ‘x,yd’ filename

Пример: [root@rhel7 ~]# sed '3,5d' a.txt

2. Просмотреть весь файл, за исключением заданного диапазона:

Синтаксис: sed ‘x,yd’ filename

Пример: [root@rhel7 ~]# sed '2,4d' a.txt

Чёртова магия! Одна команда и просматривает строки и удаляет их. Статья была бы лучше, если бы вначале набросали общий синтаксис. Он очень простой, в один абзац можно уложиться.

1.1 Использовать флаг /i:

Это расширение GNU, кстати

$ echo "Welcome To The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g'

Код выше можно сократить до
$ echo "Welcome To The Geek Stuff" | sed 's/\b[A-Z]/(&)/g'

Еще примеры

показать только первую и последнюю строки (комбинация head -1/tail -1)
sed -n '1p;$p'

Объединить все строки (аналог paste -sd ' ')
sed ":a;N;s/\n/ /;ta"

Объединить строки попарно
sed "N;s/\n/ /"

Своп каждой пары строк
sed -n '$p;h;n;G;p'

Сравнить две строки и вывести общий совпадающий фрагмент (начало строк)

sed -n 'N;s/\(.*\).*\n\1.*/\1/p'

Зарегистрируйтесь на Хабре, чтобы оставить комментарий