Bash

如何在 bash 中使用多字元分隔符進行數組擴展?

  • December 17, 2015

我將問題簡化為(我相信)最簡單的情況。假設我有一個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

引用自:https://unix.stackexchange.com/questions/235507