Bash - Continuous String Manipulation
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.)
Boathouse
Updated on September 18, 2022Comments
-
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 over 12 yearsSince 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.