连接所有参数并用双引号将它们包装起来

时间:2010-06-23 17:54:37

标签: string bash shell concatenation

function foo() {
A=$@...
echo $A
}

foo bla "hello ppl"

我希望输出为:
“bla”“你好ppl”

我需要做什么而不是省略号?

6 个答案:

答案 0 :(得分:23)

@msw有正确的想法(在问题的评论中)。但是,使用引号打印参数的另一个想法是:使用隐式迭代printf

foo() { printf '"%s" ' "$@"; echo ""; }

foo bla "hello ppl"
# => "bla" "hello ppl"

答案 1 :(得分:6)

使用参数替换添加“作为前缀和后缀:

function foo() {
    A=("${@/#/\"}")
    A=("${A[@]/%/\"}")
    echo -e "${A[@]}"
}

foo bla "hello ppl" kkk 'ss ss'

输出

"bla" "hello ppl" "kkk" "ss ss"

答案 2 :(得分:3)

您可以使用“$ @”将每个参数视为一个单独的参数,然后循环遍历每个参数:

function foo() {
for i in "$@"
do
    echo -n \"$i\"" "
done
echo
}

foo bla "hello ppl"

答案 3 :(得分:3)

ninjalj有正确的想法,但引用的使用很奇怪,部分原因是OP所要求的并不是许多shell任务的最佳输出格式。实际上,我无法弄清楚预期的任务是什么,但是:

function quote_args {
   for i ; do
      echo \""$i"\"
   done
}

将其引用的参数放在每行一个,这通常是提供其他程序的最佳方式。您确实以您没有要求的形式获得输出:

$ quote_args this is\ a "test really"
"this"
"is a"
"test really"

但它可以很容易地转换,这是大多数shell调用更喜欢的习惯用法:

$ echo `quote_args this is\ a "test really"`
"this" "is a" "test really"

但除非它经过另一个eval通过,额外的引号可能会搞砸了。也就是说,ls "is a file"会在

时列出文件is a file
$ ls `quote_args is\ a\ file`

会尝试列出您可能不想要的"isafile"

答案 4 :(得分:2)

不需要循环:

foo() { local saveIFS=$IFS; local IFS='"'; local a="${*/#/ \"}"; echo "$a"\"; IFS=$saveIFS; }

在这个简单的示例中不需要保存IFS,尤其是在函数退出之前恢复它,因为使用了local。但是,我将其包括在内,以防其他事情进入更改IFS可能影响的函数。

示例运行:

$ foo a bcd "efg hij" k "lll mmm nnn " ooo "   ppp   qqq   " rrr\ sss
 "a" "bcd" "efg hij" "k" "lll mmm nnn " "ooo" "   ppp   qqq   " "rrr sss"

答案 5 :(得分:1)

此时唯一的解决方案是尊重参数内的反斜杠和引号:

$ concatenate() { printf "%q"" " "$@"; echo ""; }
$ concatenate arg1 "arg2" "weird arg3\\\\\\bbut\" legal!"
arg1 arg2 weird\ arg3\\\\\\bbut\"\ legal\!

注意"%q"" "

  

%q ARGUMENT以可以作为shell重用的格式打印   输入,转义不可打印的字符                 建议POSIX $''语法。

特殊字符(\\b退格,...)确实会被接收程序解释,即使未在终端输出中显示解释。

让我们测试一下:

# display.sh: Basic script to display the first 3 arguments passed
echo -e '#!/bin/bash'"\n"'echo -e "\$1=""$1"; echo -e "\$2=""$2"; echo -e "\$3=""$3"; sleep 2;' > display.sh
sudo chmod 755 display.sh

# Function to concatenate arguments as $ARGS
# and "evalutate" the command display.sh $ARGS
test_bash() { ARGS=$(concatenate "$@"); bash -c "./display.sh ""$ARGS"; }

# Test: Output is identical whatever the special characters
./display.sh arg1 arg2 arg3
test_bash    arg1 arg2 arg3

更复杂的测试:

./display.sh arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"
test_bash    arg1 "arg2-1:Y\b-2:Y\\b-3:Y\\\b-4:Y\\\\b-5:Y\\\\\b-6:Y\\\\\\b" "arg3-XY\bZ-\"-1:\-2:\\-3:\\\-4:\\\\-5:\\\\\-6:\\\\\\-"

display.sh中,我们使用echo -e代替echoprintf来解释特殊字符。如果被调用的程序解释它们,这只是代表性的。

  

-e 启用反斜杠转义的解释

     

如果-e生效,则识别以下序列:

     
      
  • \ backslash
  •   
  • \ a alert(BEL)
  •   
  • \ b退格
  •   
  •   

注意:\b是退格符,因此它会删除示例中的Y.

请注意,此示例不能在实际代码中复制:

感谢接受的答案和Danny Hong answer in"如何在双引号内避免双引号?"