Reputation: 99
I want to produce a relative path from a given absolute path and store it in a variable.
/aaa/bbb/ccc/ddd/eee.txt
should be producing ../../../..
which I can append to some other path as per the requirement.
$filepath=/aaa/bbb/ccc/ddd/eee.txt
I want to create a new variable called $abs
which shall contain ../../../..
.
Tried this:
echo "$filepath" | sed -r 's/*/../g'
The above-said template is not working as per the requirement.
Being a newbie I might be asking foolish question.
Please excuse and thanks in advance!
Upvotes: 1
Views: 150
Reputation: 20002
You can avoid escaping slashes with another character like #
.
First you cut off the filename from the path with "${filepath%/*}" (better than basename
).
You replace every string with at least one character by dots.
And finally remove the starting slash.
echo "${filepath%/*}"| sed 's#[^/]\+#...#g;s#\/##'
Upvotes: 1
Reputation: 674
I am not sure sed is capable of this but, can show an awk command that do it.
echo "$filepath" | awk -F'/' '{ for ( i = 2; i < NF-1; i++ ) printf "../" } END{print ".."}'
where
-F '/'
is the field separator
is separate the text /aaa/bbb/ccc/ddd/eee.txt
into 6 sections, each section is can be used as a variable in awk, this also cause it remove field separator /
in this case, from the text.
$1
is ''
empty as first / not have anything before it.$2
is aaa
$3
is bbb
$4
is ccc
$5
is ddd
$6
is eee.txt
NF
variable contain how many field we have.
for ( i = 2; i < NF-1; i++ )
is for cycle
I start at 2 instead of 1 as first field is always empty, cause absolute path always start with /
, this will ignore that field.
I also subtract NF
variable with 1
as last field, will contain the file name, hence it is not a directory, however this allow a issue to happen if it is a directory and there is no /
at the end of it like /home/jondoe
you will end with ..
instead of ../..
while /home/jondoe/
will work.
printf "../"
get printed next to each other in each cycle as long for cycle is go.
END{print ".."}
will print ..
regardless what happened is the input. This will cause the .. at the end of the text while for cycle only print ../
repeatedly
This command still can be improved to eliminate pitfalls, like the one I mentioned. I hope this suit your needs.
Upvotes: 1