LINUX.ORG.RU

sed и пути


0

1

возникла задача заменить через sed один путь на другой, но поиграв с одинарными/двойными кавычками, а так же с конвеерами аля |$(echo)| не смог заменит один путь на другой, ибо слешы слешы слешы.

собственно как можно побороть эту гадость, чтобы сработала такого рода конструкция

path2=/usr/vat/blablabla

sed «s/\/tmp/$path2/g»

?

[17:58:12][aitap@flyingteapot ~]> path=/somewhere/in/time
[18:01:08][aitap@flyingteapot ~]> echo /tmp | sed «s|/tmp|$path|g»
/somewhere/in/time
[18:01:34][aitap@flyingteapot ~]>

AITap ★★★★★
()
Ответ на: комментарий от AITap

я правильно понимаю, что слеш/собака/вертикальнаячерта после s указывает на разделитель между паттерном и строкойдлязамены и модификатором?

loginrl103
() автор топика
Ответ на: комментарий от AITap

Плохой вариант, потому что путь к файлу запросто может содержать вертикальную черту.

Кроме того, имя файла может содержать символы, которые имеют специальное значение для sed. Это, например, &.

Правильный вариант это предварительно обработать строку $path, экранировав в ней все специальные символы, например, слеши, бек-слеши, доллары и что там еще.

Тогда будет работать всегда, здорово и вечно, штаны сухие и дети не плачут.

anarquista ★★★★★
()
Ответ на: комментарий от AITap

эта проблема возникла при написании скриптов для бекапа.

хотелось бы увидеть вариант для «предварительно обработать строку $path, экранировав в ней все специальные символы, например, слеши, бек-слеши, доллары и что там еще.»

скоко десятков строк оно займёт?

loginrl103
() автор топика
Ответ на: комментарий от loginrl103

Вот такое регулярное выражение экранирует все символы из нужного диапазона: s/([$/\\ и так далее])/\\\1/g

Вопрос: $path захардкодена или получается динамически?

AITap ★★★★★
()
Ответ на: комментарий от loginrl103

Тогда один раз вручную заэкранируйте все нехорошие символы, а в дальнейшем заменяйте по регулярному выражению вида s|/tmp|$path|.

Пути вида /tmp тоже, надеюсь, захардкодены?

AITap ★★★★★
()
Ответ на: комментарий от anarquista

> sed 's/\\/\\\\/g;s/[&/]/\\&/g'

нечитабельно же...

предлагаю `awk': «echo ... | awk -v old=... -v new=... 'sub(old,new)'» (`-v' как подобие интерфейса наружу)

n01r ★★
()
Ответ на: комментарий от anarquista

> В new тоже могут быть специальные символы. & и \ все равно нужно экранировать.

Точно, лажанул. & - не считается ): забыл, что `sub' - регекспы принимает, а \ - вроде не обойти...

Все равно это не отменяет нечитабельность `sed'. Тогда python "... .replace(old, new)", или (башизм?, dash не умеет, а sh как линк на bash заменяет) «${../$old/$new}».

n01r ★★
()
Ответ на: комментарий от n01r

Мне кажется, что замена sed,awk и т.п. чем-то другим это плохой путь. Иметь возможность использовать специальные символы типа & при работе с регулярными выражениями — это удобно, это правильно.

Экранирование символов — это настолько обыденное, повседневное дело, что ничего не понятногов нем быть не может.

anarquista ★★★★★
()
Ответ на: комментарий от anarquista

> что ничего не понятногов нем быть не может

Дык, надо экранировать все символы из BRE, а если `sed -r', то и из ERE... В данном случае ($...) видимо запускается из bash/sh, можно его средствами (в крайнем случае для `dash' возможны ${text%%$old*}$new${text#*$old})

что замена sed,awk и т.п. чем-то другим это плохой путь

а использовать регэспы для обычной замены - правильный?

n01r ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.