Bash - Continuous String Manipulation

9,750

Solution 1

FILE=$(basename "${1/%.jpeg/.jpg}") worked for me.

test:

bash-$ ./test.sh /tmp/foo.jpeg
foo.jpg

script contents:

bash-$ cat test.sh 
#!/usr/bin/bash

FILE=$(basename "${1/%.jpeg/.jpg}")

echo "$FILE"

Solution 2

You can't nest expansions in bash (nor in ksh, ash and other shells apart from zsh). This is only a cosmetic limitation, since as you illustrate you can assign an intermediate expression to a temporary variable. It is a little annoying for one-liners, but in scripts it's arguably better for readability.

You could avoid using the external utility basename and use a string manipulation construct instead:

FILE="${1##*/}"; FILE="${FILE/%.jpeg/.jpg}"

Here, it happens that you can rewrite your script to put the command substitution on the outside. That's not a general phenomenon, nor do you gain anything other than a certain one-liner feeling.

Zsh, for better or for worse, does let you nest expansions:

FILE=${$(basename $1)/%.jpeg/.jpg}    # using basename
FILE=${${1##*/}/%.jpeg/.jpg}          # using string rewriting

Or you could use zsh's built-in construct instead of basename:

FILE=${${1:t}/%.jpeg/.jpg}

Solution 3

I'd go for :

FILE=$(basename $1 .jpeg).jpg

The second parameter to basename is a suffix to be removed from the file name (see man basename)

Solution 4

You could use a single sed command as in the following:

FILE=$(sed 's/.*\///;s/\.jpeg$/.jpg/' <<<"$1")

Solution 5

Incorporating sed, this should do the trick:

FILE="$(basename "$1" | sed s/\.jpeg$/.jpg/)"

(This doesn't exactly answer your question because I can't; not sure if it's possible.)

Share:
9,750
Boathouse
Author by

Boathouse

Updated on September 18, 2022

Comments

  • Boathouse
    Boathouse almost 2 years
    #!/bin/bash
    
    FILE="$(basename "$1")"
    FILE="${FILE/%.jpeg/.jpg}"
    

    Is there anyway to glue these two lines together into a one-liner?

  • Boathouse
    Boathouse over 12 years
    Since the two lines are kinda interchangable, this solution is so far the neatest... If the lines aren't interchangable sed will be definitely needed I guess.