83

I'm trying to replace /./ or /././ or /./././ to / only in bash script. I've managed to create regex for sed but it doesn't work.

variable="something/./././"
variable=$(echo $variable | sed "s/\/(\.\/)+/\//g")
echo $variable # this should output "something/"

When I tried to replace only /./ substring it worked with regex in sed \/\.\/. Does sed regex requires more flags to use multiplication of substring with + or *?

Cœur
  • 37,241
  • 25
  • 195
  • 267
J33nn
  • 3,034
  • 5
  • 30
  • 46

4 Answers4

109

Use -r option to make sed to use extended regular expression:

$ variable="something/./././"
$ echo $variable | sed -r "s/\/(\.\/)+/\//g"
something/
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • 24
    FYI - extended regular expressions are enabled via '-E' on OSX & BSD. Thanks for pointing me in the right direction (rtfm for 'extended')! – nevelis Sep 30 '16 at 18:41
4

Any sed:

sed 's|/\(\./\)\{1,\}|/|g'

But a + or \{1,\} would not even be required in this case, a * would do nicely, so

sed 's|/\(\./\)*|/|g'

should suffice

Scrutinizer
  • 9,608
  • 1
  • 21
  • 22
3

Two things to make it simple:

$ variable="something/./././"
$ sed -r 's#(\./){1,}##' <<< "$variable"
something/
  • Use {1,} to indicate one or more patterns. You won't need g with this.
  • Use different delimiterers # in above case to make it readable
  • + is ERE so you need to enable -E or -r option to use it
jaypal singh
  • 74,723
  • 23
  • 102
  • 147
2

You can also do this with bash's built-in parameter substitution. This doesn't require sed, which doesn't accept -r on a Mac under OS X:

variable="something/./././"
a=${variable/\/*/}/                   # Remove slash and everything after it, then re-apply slash afterwards
echo $a
something/

See here for explanation and other examples.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432