Still getting the hang of bash scripting...
I have a function that resizes images and calculates how much to scale it based on the file size. I need to pass this percentage as an argument to the convert command, but I can't remove the return from the end of the string.
When I run the function, I get:
2.362413
%How can I concatenate these on one line without a return or newline char? Piping to tr with '\r' or '\d' doesn't seem to work.
shrinkImg() { FILENAME=$(basename "$1") EXTENSION="${FILENAME##*.}" sz=$(stat -c '%s' $1) PRODUCT=echo bc <<< "scale = 10; ( 100 / ( $sz / 350000))"; PRODUCT=echo ${PRODUCT} | tr -d '\r' PERCENT=% TARGET=echo $TARGET TARGET=$PRODUCT$PERCENT echo $TARGET; if [ $sz -ge 350000 ] && [ $EXTENSION == 'png' ] ; then convert $1 -resize $TARGET $1 elif [ $sz -ge 350000 ] && [ $EXTENSION == 'PNG' ] ; then convert $1 -resize $TARGET $1 elif [ $sz -ge 350000 ] && [ $EXTENSION == 'jpg' ] ; then convert $1 -resize $TARGET $1 elif [ $sz -ge 350000 ] && [ $EXTENSION == 'JPG' ] ; then convert $1 -resize $TARGET $1 fi }Also any other tips would be appreciated!
22 Answers
There are several weird lines in the code.
For example:
PRODUCT=echo ${PRODUCT} | tr -d '\r'This assigns the string "echo" into $PRODUCT, and runs ${PRODUCT} | tr -d '\r' with the previous value of $PRODUCT.
What you need is command substitution:
filename=${1##*/}
extension=${filename##*.}
sz=$(stat -c %s "$1")
product=$(bc <<< "scale = 10; ( 100 / ( $sz / 350000))")
echo $product% I took a different approach to improvement... No piping to tr, and just making the '%" part of the output. Then since all the if elsif statements were complex, yet performing the same commands, I simplified them into one case statement.
shrinkImg() { FILENAME=$(basename "$1") EXTENSION="${FILENAME##*.}" sz=$(stat -c '%s' $1) TARGET=$(echo 35000000 | awk '{print $1/'$sz')"%"}') echo $TARGET if [ $sz -ge 350000 ]; then case $EXTENSION in png|PNG|jpg|JPG) convert $1 -resize $TARGET $1;; *) echo "Unexpected extension, $EXTENSION";; esac fi
}The TARGET variable is a bit more confusing now, but I wanted to demonstrate an alternative to your bc command. Awk does math, and can format output too.
To break it down, awk is is passed the constant value of 35000000 (this number was 350000, but I multiplied by 100 to convert decimal to percent) and tracks this field/value as "$1". Since $sz is not defined or set from inside of awk itself, we break out of the awk by closing the single quote and reaching into the previous level of the the function to get the value of $sz. Then we end that call out by starting our single quotes again. With all the math organized, we print the result including an appended a percent sign.
Without the percent sign, the decimal has to move again.