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
  • 1
    Before or after '-'? – Pilot6 Jun 8 '16 at 12:21
  • i need a portion before '-' – RNA Jun 8 '16 at 12:23
  • See the answer. – Pilot6 Jun 8 '16 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 '16 at 10:46
  • i tried TRIMMED3="${TRIMMED2%%-*}" and it returned A – RNA Jun 20 '16 at 10:48
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.

| improve this answer | |
  • what does ${@:2} means? – RNA Jun 8 '16 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 '16 at 13:01
  • Could you please add a link to "${1%-*}" "${@:2}" etc guide? have no idea what to google :) – Putnik Jun 8 '16 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 '16 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 '16 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.

| improve this answer | |
  • I fixed it. I put f and d at wrong places. Now it is OK. – Pilot6 Jun 8 '16 at 12:25
  • No, I do not... – Pilot6 Jun 8 '16 at 12:34
  • i tried ur method and it gives un-trimmed $1 – RNA Jun 8 '16 at 12:38
  • @muru The other quotes are no needed either I guess ;-) – Pilot6 Jun 8 '16 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 '16 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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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