I am trying to write a shell script that will need to transform input of the following form:
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
Into:
baz-qux
quz
foo
I.e. split on '/', drop the first 2 segments, drop the '.txt' and substitute remaining slashes for hyphens.
The substitution seems straightforward enough using tr:
paths=$(cat <<- EOF
foo/bar/baz/qux.txt
bar/baz/quz.txt
baz/quz/foo.txt
EOF
)
echo $paths | tr '/' '-' | tr '.txt' ' '
I've tried various forms of
cut -d '/' -f x
To get the necessary segments but am coming up short.
I'm a ruby guy so tempted to reach for my hammer and just use ruby:
lines.each { |s| s.split('/')[2..-1].join('-').split('.')[0] }
But deploying ruby for this one operation seems like it might be overkill. And I would like to improve my shell skills anyway so was wondering if there is a more elegant way anyone would recommend to do this in shell?
Thanks for any help
It can be done using bash
parameter expansions:
for name in foo/bar/baz/qux.txt bar/baz/quz.txt baz/quz/foo.txt; do
new=${name#*/} # drop the shortest prefix match for */, thus everything up to first /
new=${new#*/} # repeat, dropping the second segment
new=${new%.txt} # drop shortest suffix match for .txt
new=${new//\//-} # convert any remaining slashes
echo "$new"
done
Gives:
baz-qux
quz
foo
These are all bash
shell built-in constructs, so no external processes like cut
, sed
or tr
required.