Комментарии 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'
Команда SED в Linux/Unix с примерами