反转参数列表和最后的双引号

reversing argument list and lost doublequotes

重新访问将图像附加在一起的简单脚本,因为路径中的空格有问题。

输出正确,但 path/filenames 的双引号不存在,因此转换失败。

我很确定这是一个简单的语法修复。建议? ...也许我最好在文件参数之前使用模式参数,然后用 shift 将其关闭?

#!/bin/bash
# BETLOG - 2015-05-05--22-17-35
#
# usage:
# betlogImageAppend.sh %F row/wor/col/loc
# # 
mode=${!#} #last arg
set -- "${@:1:$(($#-1))}" #strip last arg: mode
#echo -ne "\n\n0 @=${@}\n\n"
case "$mode" in
    row) 
        mode="+append"
        in=$@
    ;;
    wor)
        mode="+append"
        in="$(printf '%s\n' "$@" | tac)"
    ;;
    col)
        mode="-append"
        in=$@
    ;;
    loc)
        mode="-append"
#         in=$(printf '%s\n' ${@} | tac)
#         in=`printf '%s\n' "${*}" | tac`
        in=$(printf '%s\n' "$@" | tac)
    ;;
esac

echo "convert "${in}" $mode $(date +%Y-%m-%d--%H-%M-%S).jpg"
# # # convert ${in} $mode $(date +%Y-%m-%d--%H-%M-%S).jpg

我正在测试 'loc'(反向列),因此进行了各种试验。 仅供参考:row/wor/col/loc = row/reversed row/column/reversed 列

当你这样做时:

in='smth with space.jpg
another with space.jpg'
convert "${in}" ...

"$in"被解释为一个参数。这意味着 convert 将搜索名为 smth with space.jpg\nanother with space.jpg 的单个文件而不是两个文件。如果你要写 convert $in ... 那么 in 会展开并且不会被包含,space 和换行符被解释为分隔符,所以它有 6 个文件,即。名为 smth 的文件、名为 with 的文件等等。作为这个问题的解决方案,我们可以使用 bash 数组并始终记住正确转义您的参数。

mode=${!#} #last arg
set -- "${@:1:$(($#-1))}" #strip last arg: mode
case "$mode" in
row) mode="+append"; in=("$@"); ;;
                         # `for i;` is a shorter version of `for i in "$@";`
wor) mode="+append"; in=(); for i; do in=("$i" "${in[@]}"); done; ;; 
col) mode="-append"; in=("$@"); ;;
loc) mode="-append"; in=(); for i; do in=("$i" "${in[@]}"); done; ;;
esac

printf "arg: '%s'\n" convert "${in[@]}" "$mode" "$(date +%Y-%m-%d--%H-%M-%S).jpg"
# convert "${in[@]}" "$mode" "$(date +%Y-%m-%d--%H-%M-%S).jpg"

这样的脚本应该适用于任何文件名,spaces 或换行符。

太好了,谢谢。成功了。我知道我的 array-fu 让我失望了。

#!/bin/bash
# usage:
# betlogImageAppend.sh %F row/wor/col/loc
mode=${!#} #last arg
set -- "${@:1:$(($#-1))}" #strip last arg: mode
case "$mode" in
    row) mode="+append"; in=("$@"); ;;
    wor) mode="+append"; in=(); for i; do in=("$i" "${in[@]}"); done; ;; # `for i;` is a shorter version of `for i in "$@";`
    col) mode="-append"; in=("$@"); ;;
    loc) mode="-append"; in=(); for i; do in=("$i" "${in[@]}"); done; ;;
esac
convert "${in[@]}" "$mode" "$(date +%Y-%m-%d--%H-%M-%S).jpg"