10
#!/bin/bash

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

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

12

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"
  • 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. – gsklee Nov 8 '11 at 22:21
10

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}
4

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)

3

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

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

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.)

1

The Bash ${} constructs work with variable names, so there's no way to embed a command directly. @sr_'s approach is an alternative if you don't mind the extra fork.

1

The line

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

can be shortened and made more portable with

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

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.