Mat
Mat

Reputation: 1101

Strip double dots from path in bash

I wonder how it would be possible to use a regular expression to simplify double dots from a file path (the path may not actually exist) ?

For example change /my/path/to/.././my/./../../file.txt into /my/file.txt or path/./to/../../../file.txt into ../file.txt.

Is it possible to do this in one command in bash ? (using sed for example, not a complicated python or perl script)

edit: I came across this question but realpath isn't available on the computer I use.

edit: From F.J 's solution, I ended up building the following regex which works in more general cases (does not work if some folder of the path is named ....):

sed -e 's|/\./|/|g' -e ':a' -e 's|\.\./\.\./|../..../|g' -e 's|^[^/]*/\.\.\/||' -e 't a' -e 's|/[^/]*/\.\.\/|/|' -e 't a' -e 's|\.\.\.\./|../|g' -e 't a'

Upvotes: 1

Views: 2903

Answers (1)

Andrew Clark
Andrew Clark

Reputation: 208615

Try the following:

sed -e 's|/\./|/|g' -e ':a' -e 's|/[^/]*/\.\./|/|' -e 't a'

Example:

$ echo '/my/path/to/.././my/./../../file.txt' |
  sed -e 's|/\./|/|g' -e ':a' -e 's|/[^/]*/\.\./|/|' -e 't a'
/my/file.txt

Here is a description of the approach:

read line
replace all '/\./' in line with '/'
while there is a match of '/[^/]*/\.\./' {
    replace first occurrence of '/[^/]*/\.\./' in line with '/'
}
output line

Upvotes: 4

Related Questions