Как заменить путь другим путем в sed?
У меня есть csh script (хотя я могу менять языки, если он имеет какую-либо значимость), где я должен:
sed s/AAA/BBB/ file
Проблема заключается в том, что AAA и BBB являются путями, и поэтому содержат '/'. AAA фиксирован, поэтому я могу сказать:
sed s/\\\/A\\\/A\\\A/BBB/ file
Однако BBB основан на переменных, включая $PWD. Как избежать "/" в $PWD?
ИЛИ есть ли другой способ, которым я должен делать это полностью?
Ответы
Ответ 1
sed
может использовать любой разделитель вместо /
в команде s
. Просто используйте то, что не встречается на ваших путях:
s+AAA+BBB+
и т.д.
Альтернативно (и если вы не хотите догадываться), вы можете предварительно обработать свой путь с помощью sed, чтобы избежать косой черты:
pwdesc=$(echo $PWD | sed 's_/_\\/_g')
а затем сделайте то, что вам нужно, с помощью $pwdesc
.
Ответ 2
В тех случаях, когда строка замены или строка шаблона содержат косые черты, вы можете использовать тот факт, что GNU sed позволяет альтернативный разделитель для команды substitute. Общий выбор разделителя - символ трубы | или хэш # - лучший выбор разделительного символа часто зависит от типа обрабатываемого файла. В вашем случае вы можете попробовать
sed -i 's#/path/to/AAA#/path/to/BBB#g' your_file
Примечание: g после последнего # заключается в изменении всех вхождений в файле, если вы хотите изменить первую ouccurence, не используйте g
Ответ 3
Использование csh
для серьезных сценариев обычно не рекомендуется. Тем не менее, это имеет отношение к данной проблеме.
Вы, вероятно, после чего-то вроде:
sed -e "s=$oldpath=$newpath="
где переменная оболочки $oldpath
содержит значение, подлежащее замене, а $newpath
содержит замену, и предполагается, что ни одна из переменных не содержит знак равенства. То есть вам разрешено выбирать разделитель в шаблоне, а избегание обычного /
разделителя позволяет избежать проблем с косой чертой в путевых именах. Если вы думаете, что =
может появиться в именах файлов, выберите что-то менее вероятное, например control-A или control-G.
Ответ 4
sed -i "s|$fileWithPath|HAHA|g" file
Ответ 5
Вы можете использовать расширение скобок ${i/p/r}
, чтобы избежать косой черты.
В этом случае ${i//p/r}
для экранирования всех вхождений.
$p1=${p1//\//\\/}
$p2=${p2//\//\\/}
sed s/$p1/$p2/ file
Или, более кратким, в одной строке sed s/${p1//\//\\/}/${p2//\//\\/}/ file
Два кулачных слэша //
являются разделителями в расширении в скобках, говорящими, что мы сопоставляем все вхождения, тогда \/
предназначен для экранирования косой черты в шаблоне поиска, /
в качестве второго разделителя в расширении и то \\/
является заменой, в противном случае обратная косая черта должна быть экранирована.
Ответ 6
Нам просто нужно было получить ссылки на /h/network path из пути. если мы указываем их обратно на диск /c/, они сопоставляются с несуществующими каталогами, но быстро разрешаются. В моем .bashrc я использовал
PATH='echo $PATH | sed -e "s+/h/+/c/+g"'