URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 10344
[ Назад ]

Исходное сообщение
"sed/grep - заменить вхождение строки"

Отправлено Аноним , 29-Дек-20 10:55 
Добрый день. Мне нужно заменить все вхождения строки в файле, но только в тех случаях, когда некоторая последовательность в строке не найдена. Возможно ли это осуществить в sed, как будет выглядеть регулярное выражение? Спасибо.

Также я пытался подобрать подходящий паттерн для grep, тоже ничего не получилось. Мне нужны все совпадения строк, только если строка не включает в себя другую строку ("решено" цепочкой из 2 grep).

В общем-то, я озаботился из-за того, что это достаточно частая задача. И я не совсем понимаю, как её решить в sed.


Содержание

Сообщения в этом обсуждении
"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 11:11 
Как-то так:

grep -v "решено" filename.txt |sed -E 's/pattern/замена/'


"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 11:39 
Это не то. Мне нужно заменить строки в файле и сохранить неподходящие нетронутыми. Допустим есть файл со строками

gsjxfjhdfsjgkd    abc jkd^$!sgjh
kld'lkhg  abc drty&tsf \
g!"hs cba ^^^^^^^^^^^^\;& abc    ;lj

мне нужно заменить только строки с abc и не трогать те, в которых имеется cba, при этом желательно сматчить все элементы (особенно строку до совпадения и строку после) в группы, чтобы на них можно было ссылаться.

"sed/grep - заменить вхождение строки"
Отправлено universite , 29-Дек-20 15:13 
> Это не то. Мне нужно заменить строки в файле и сохранить неподходящие
> нетронутыми. Допустим есть файл со строками
>
gsjxfjhdfsjgkd    abc jkd^$!sgjh 
> kld'lkhg  abc drty&tsf \
> g!"hs cba ^^^^^^^^^^^^\;& abc    ;lj

> мне нужно заменить только строки с abc и не трогать те, в
> которых имеется cba, при этом желательно сматчить все элементы (особенно строку
> до совпадения и строку после) в группы, чтобы на них можно
> было ссылаться.

Значит, набирайте тестовый набор данный и делайте регулярку.


"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 15:45 
Я пытался добавить условия к паттерну, чтобы он не совпадал при совпадении некоторой подстроки, но в результате у меня получилось только собрать и совпадающие и не совпадающие строки. Это не работает, поскольку это одновременно одна и та же строка будет. Перловое lookahead тоже не подошло -- либо это не то, что мне нужно, либо я не понял, как в данном случае применить (в идеале перла нужно избежать).

"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 15:25 
> Это не то. Мне нужно заменить строки в файле и сохранить неподходящие
> нетронутыми. Допустим есть файл со строками
>
gsjxfjhdfsjgkd    abc jkd^$!sgjh 
> kld'lkhg  abc drty&tsf \
> g!"hs cba ^^^^^^^^^^^^\;& abc    ;lj

> мне нужно заменить только строки с abc и не трогать те, в
> которых имеется cba, при этом желательно сматчить все элементы (особенно строку
> до совпадения и строку после) в группы, чтобы на них можно
> было ссылаться.


cat input.txt

gsjxfjhdfsjgkd    abc jkd^$!sgjh
kld'lkhg  abc drty&tsf \
g!"hs cba ^^^^^^^^^^^^\;& abc    ;lj



grep -v "cba" input.txt | sed 's/abc/ABC/g'

gsjxfjhdfsjgkd    ABC jkd^$!sgjh
kld'lkhg  ABC drty&tsf \



"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 15:36 
Строка с cba потерялась, она просто должна остаться неизменной в результирующем файле. Поэтому должно быть правило для седа, без всяких грепов. Греп я упомянул в контексте egrep.

"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 15:38 
> Строка с cba потерялась, она просто должна остаться неизменной в результирующем файле.
> Поэтому должно быть правило для седа, без всяких грепов. Греп я
> упомянул в контексте egrep.


sed '/cba/!s/abc/ABC/g' input.txt


"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 15:50 
Это опять не регулярка, т.е. нельзя засунуть в греп, например. Ну ладно, в целом, этого достаточно для решения задачи, конечно. Благодарю.

"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 17:28 
Можно усложнить задачу? Нужно проверить чтобы каждое совпадение паттерна существовало на диске, в этом случае замену не выполнять. Либо выполнять для несуществующих файлов. Потом проверять на существование эту замену, и если ни оригинальный, ни результирующий файл по какой-то причине не существует на диске, выводить ошибку. Ведь типичная задача для sed, во всяком случае gnu sed вызывает внешние команды. Я могу вызвать из седа шелл, чтобы тот дополнил мне имя файла на диске. Или даже проверит существование и всё это, но это ведь дополнительный процесс на каждую строку и их там тысячи. Нельзя это осуществить только средствами седа?

"sed/grep - заменить вхождение строки"
Отправлено Аноним , 29-Дек-20 19:30 
С этим возник ряд проблем. Я не смог придумать как вызвать ошибку и остановить сед, пришлось заменить на текст "не найдено ххх". Вообще грязновато вышло, но забавно. Пришлось матчить все символы, а не только нужные, иначе жаловалась на $ и скобочки в строке. Буквально добавить (.*) по краям. А ещё в файле \r в строках, это я тоже не заметил заранее. А так sed exec вполне норм, справляется (через bash -c не получилось правда, пришлось однострочник в отдельный файл пихать). Видимо, ещё и extglob нужен.