Bash
如何在 bash 中使用多字元分隔符進行數組擴展?
我將問題簡化為(我相信)最簡單的情況。假設我有一個
myscript.sh
包含以下內容的腳本:#!/bin/bash IFS='%20' echo "$*"
如果我按如下方式執行命令,輸出將如下所示:
me@myhost ~ $ ./myscript.sh fee fi fo fum fee%fi%fo%fum
這是預期的行為,如
bash
手冊頁中所述:* Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a sin- gle word with the value of each parameter separated by the first character of the IFS special variable. That is, "$*" is equiva- lent to "$1c$2c...", where c is the first character of the value of the IFS variable. If IFS is unset, the parameters are sepa- rated by spaces. If IFS is null, the parameters are joined without intervening separators.
但是,我想得到的是輸出:
fee%20fi%20fo%20fum
因此使用多字元分隔欄位而不是單個字元。
有沒有辦法做到這一點
bash
?更新:
基於下面 mikeserv 的數據,以及為什麼 printf 比 echo 更好?,我最終做了以下事情(再次簡化為上例中最簡單的情況):
#!/bin/bash word="$1" shift if [ "$#" -gt 0 ] ; then word="$word$(printf '%%20%s' "$@")" fi printf '%s\n' "$word" unset word
printf
將其格式字元串應用於輸出時跟隨它的每個參數。它是一個bash
內置的 shell,可用於將分隔符字元串應用於參數列表 - 有點。例如:
printf %s:delimit: arg1 arg2 arg3
arg1:delimit:arg2:delimit:arg3:delimit:
問題是,
printf
不會停止在其參數末尾應用其格式字元串,因此最後一個會獲得附加的分隔符。在某些情況下可以處理:printf %b:delimit: \\0150 \\0145 \\0171\\c
h:delimit:e:delimit:y
printf
將 C 和八進制轉義解釋為%b
具有某種格式的 ytes,並且還具有%b
您\c
在某個點輸出其輸出的格式,這就是為什麼printf
不使用:delimit:
字元串跟隨上面的 y 的原因,因為它的格式字元串會以其他方式指示。因此,如果您希望每個參數都按字面意思解釋並且沒有尾隨分隔符,那麼您必須在參數列表本身中解決問題:
set -- arg1 arg2 arg3 for arg do shift set -- "$@" :delimit: "$arg" done; shift printf %s "$@"
arg1:delimit:arg2:delimit:arg3