Косая черта /
и точка .
являются специальными символами регулярного выражения для sed
, поэтому их необходимо экранировать, если они используются для своих буквенных символов.
Точка - это подстановочный знак из одного символа, поэтому ..
соответствует любым двум символам , а не буквальным двум точкам.
Косая черта разделяет поиск, замену и флаги, как man-страница для состояний sed /regular expression/replacement/flags
- так что ваш шаблон поиска должен избегать обоих, делая его
sed 's/\.\.\/\.\.\/\.\./home/g' file > newfile
Это довольно уродливо, но sed может использовать что-то отличное от /
в качестве разделителя. Мой любимый альтернативный вариант - ~
, поэтому команда станет
sed 's~\.\./\.\./\.\.~home~g' file > newfile
Обновление
Отвечая на комментарий @Gu Buddy ...
Я не знаю, что это "более элегантно", но есть и другие способы подойти к этому.
Специальные символы, такие как .
*
/
, теряют свое специальное значение при использовании в классе символов, поэтому [.]
просто означает period , а не «любой символ», так что вы можете избежать их
sed 's/[.][.][/]/dot-dot-slash/g' file
sed 's/[.][.][/][.][.][/][.][.]/home/g' file
Вы также можете использовать счетчик совпадений (повторений) - число или диапазон в фигурных скобках, применяемый к предшествующему ему символу или группе - но их необходимо экранировать, если вы не используете расширенные регулярные выражения («ERE» против базового регулярного выражения «BRE»), включается с помощью флага -E
:
sed 's~\([.][.][/]\)\{3\}~home/~' file # with BRE
group start-^ grp end-^ ^-count
sed -E 's~([.][.][/]){3}~home/~' file # with ERE
sed -E 's~([.]{2}[/]){3}~home/~' file # also ERE
Обратите внимание, что в моем исходном ответе я избегал замены третьего слеша, оставляя его там, чтобы отделить замену "home" от оставшегося пути ...
../../../
^
... но при использовании повторения {3}
он совпадет и заменит этот третий слеш, поэтому я должен включить слеш после home в строке замены.
Я проверил все это на файле, который просто содержит это:
../../../this/that/file.txt
../../../some/otherfile.txt
получить этот вывод:
home/this/that/file.txt
home/some/otherfile.txt