3

OK, here is a given user input :

$ myscript.sh file-name.txt

I would like to trim "file-name.txt" to retrive 'file' in bash script

#!/bin/bash
FILENAME=$1

# trim text after '-' from user input 'file-name.txt'
# save 'file' back to $1

My best guess is mixing sed and regular expression somehow, but I am no expert of those :(

Any ideas?


I tried muru's suggestion for more complicated input.

given input : A-B-C-D-0.1.5-6.1.txt

wanted output : A-B-C-D

#!/bin/bash
TRIMMED1="${1%-*}"
TRIMMED2="${1%%-*}"
TRIMMED3="${TRIMMED1%-*}"
TRIMMED4="${TRIMMED1%%-*}"
TRIMMED5="${1%-[0-9]*}"
TRIMMED6="${1%%-[0-9]*}"
echo "user input : $1"
echo "TRIMMED1 : $TRIMMED1"
echo "TRIMMED2 : $TRIMMED2"
echo "TRIMMED3 : $TRIMMED3"
echo "TRIMMED4 : $TRIMMED4"
echo "TRIMMED5 : $TRIMMED5"
echo "TRIMMED6 : $TRIMMED6"

result:

user input : A-B-C-D-0.1.5-6.1.txt
TRIMMED1 : A-B-C-D-0.1.5
TRIMMED2 : A
TRIMMED3 : A-B-C-D
TRIMMED4 : A
TRIMMED5 : A-B-C-D-0.1.5
TRIMMED6 : A-B-C-D
7
  • 1
    Before or after '-'?
    – Pilot6
    Jun 8, 2016 at 12:21
  • i need a portion before '-'
    – RNA
    Jun 8, 2016 at 12:23
  • See the answer.
    – Pilot6
    Jun 8, 2016 at 12:24
  • TRIMMED3 is supposed to re-use TRIMMED2, so the line should actually be TRIMMED3="${TRIMMED2%%-*}" , and yes - my mistake there - TRIMMED2 and TRIMMED3 should use %, not %%.
    – muru
    Jun 20, 2016 at 10:46
  • i tried TRIMMED3="${TRIMMED2%%-*}" and it returned A
    – RNA
    Jun 20, 2016 at 10:48

3 Answers 3

8

You don't have to use external tools for this. Pure bash:

FILENAME="${1%-*}"

% is used to remove the shortest matching suffix. If you have file-name-foo, you'll get file-name. To remove the longest matching suffix, use %%.

To save to $1, you'll have to use set. Something like:

set -- "${1%-*}" "${@:2}"

Then the next time you use $1, it will have the trimmed text.

Remember, no spaces around = when assigning variables.

9
  • what does ${@:2} means?
    – RNA
    Jun 8, 2016 at 12:59
  • 1
    @RNA all the arguments, from the second onwards (essentially, "$2" "$3" "$4" …), empty if you have only one argument. What that line does is set the arguments, but using a different string for the first argument.
    – muru
    Jun 8, 2016 at 13:01
  • Could you please add a link to "${1%-*}" "${@:2}" etc guide? have no idea what to google :)
    – Putnik
    Jun 8, 2016 at 13:58
  • 2
    @Putnik the BashFAQ is a good resource: mywiki.wooledge.org/BashFAQ/005#Retrieving_values_from_an_array and mywiki.wooledge.org/BashFAQ/100
    – muru
    Jun 8, 2016 at 18:41
  • 1
    @RNA if the version number's guaranteed to start with a digit, maybe: ${1%-[0-9]*}, (though that may trip over entries like foo-9bar-1.2-3. Or apply %% twice: a=${1%%-*}; a=${a%%-*} to remove the last two hyphen-separated fields
    – muru
    Jun 20, 2016 at 4:41
5

You can do it by

#!/bin/bash
FILENAME=$1
TRIMMED=$(echo "$FILENAME" | cut -f1 -d-)

The command will output field 1 using - as a delimeter.

9
  • I fixed it. I put f and d at wrong places. Now it is OK.
    – Pilot6
    Jun 8, 2016 at 12:25
  • No, I do not...
    – Pilot6
    Jun 8, 2016 at 12:34
  • i tried ur method and it gives un-trimmed $1
    – RNA
    Jun 8, 2016 at 12:38
  • @muru The other quotes are no needed either I guess ;-)
    – Pilot6
    Jun 8, 2016 at 12:39
  • You can't assign to $1 that way, unfortunately. Those quotes are needed: what will happen if filename is, for example: fi le-name.txt?
    – muru
    Jun 8, 2016 at 12:39
4

Can be done like this:

#!/bin/bash
# trim text after '-' from user input 'file-name.txt'
FILENAME="$(sed 's/-.*//' <<< $1).txt"

# save 'file' back to $1
mv "$1" "$FILENAME"

Explanation:

In my example I use the sed command to shorten the name which usually has this layout 'command/search/replacement/'. In my example above i use s as command which is search and replace, then -.* as search word (regex) which will search all combinations beginning with a - then followed by a random character . and telling it this keeps on till the end with *. The replacement string I leave empty, this means file-name.txt becomes file.

The <<< is bash specific and is called a here-string, so this wont work in sh. It is like the redirections into files just that it redirects a string into the stream instead of a file.

Finaly to make the string complete I add .txt back and then do a mv to rename the file.

4
  • I did not catch that OP wanted to mv the file.
    – Pilot6
    Jun 8, 2016 at 12:29
  • Np, you still can add it in your answer, all here are valid so far.
    – Videonauth
    Jun 8, 2016 at 12:31
  • little more explanation on the role of <<<, please.
    – RNA
    Jun 8, 2016 at 12:57
  • Added it into my answer.
    – Videonauth
    Jun 8, 2016 at 13:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .