Slash /
and dot .
are both special regex characters to sed
, so they need to be escaped if they are being used for their literal characters.
Dot is the single-character wildcard, so ..
matches any two characters, not just a literal two-dots.
Slash delimits the search, replace, and flags, as the man page for sed states /regular expression/replacement/flags
-- so your search pattern has to escape both of those, making it
sed 's/\.\.\/\.\.\/\.\./home/g' file > newfile
That gets pretty ugly, but sed can use something other than /
as the delimiter. My favorite alternate is ~
, so the command would become
sed 's~\.\./\.\./\.\.~home~g' file > newfile
Update
Responding to @Gu Buddy's comment...
I don't know that it's "more elegant", but there are other ways to approach this.
The special characters such as .
*
/
lose their special meaning when used in a character class, so [.]
just means period not "any char", so you can avoid escaping them
sed 's/[.][.][/]/dot-dot-slash/g' file
sed 's/[.][.][/][.][.][/][.][.]/home/g' file
You can also use a match count (repetition) — a number or range in curly-braces, applied to the char or group preceding it — but those have to be escaped unless you use extended regular expressions ("ERE" vs basic regex "BRE"), enabled via the -E
flag:
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
Notice in my original answer I avoided replacing the third slash, leaving it there to separate the replacement "home" from the remaining path...
../../../
^
...but using the repetition of {3}
it will match and replace that third slash, so I have to include the slash after home in the replacement string.
I tested all of these on a file that just contains this:
../../../this/that/file.txt
../../../some/otherfile.txt
getting this output:
home/this/that/file.txt
home/some/otherfile.txt