Reputation: 501
I have files which all look like this: filename.bla_1
of cours I cannot know if the filename has "_" in it. could be file_name.bla_1. I want to write a function that take filename and delete the _# at the end. filename.bla_1 will be --> filename.bla
echo $filename | rev | cut -d "_" -f2 | rev
will do the trick if the file doesn't have "" in the name but I want to make sure this works also for filenames with ""
Upvotes: 0
Views: 46
Reputation: 15273
If you care to tweak the globbing parser a little,
shopt -s extglob
for f in abc.bla a_b_c_.bla abc.bla_1 a_b_c_.bla_2 123.456.789 123.456.789_x abc_
do echo ${f%_+([^._])}
done
abc.bla
a_b_c_.bla
abc.bla
a_b_c_.bla
123.456.789
123.456.789
abc_
${f%_+([^._])}
means the value of $f
with a _
followed immediately by one or more non-dot-or-underscore
characters trimmed OFF the end.
Upvotes: 1
Reputation: 241828
You can use parameter expansion. The %
removes the shortest possible pattern on the right side of the value, ##
removes the longest possible match on the left:
#! /bin/bash
for f in filename.bla_1 \
file_name_with_underscores.foo_2 \
file_name_with_underscores.foo \
filename.with_dots.foo_2 ; do
ext=${f##*.}
basename=${f%.*}
echo "$basename.${ext%_*}"
done
Upvotes: 6
Reputation: 246774
Use @choroba's answer.
But to fix your code, after you reverse the filename, you need to take the 2nd and all following fields, not just the 2nd:
$ filename=foo_bar_baz.bla_1
$ rev <<<"$filename" | cut -d_ -f2- | rev
foo_bar_baz.bla
The -f2-
with the trailing hyphen is the magic here. Read the cut
man page.
Upvotes: 0