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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.