【问题标题】:Concatenate all arguments and wrap them with double quotes连接所有参数并用双引号括起来
【发布时间】:2011-03-07 11:04:34
【问题描述】:
function foo() {
A=$@...
echo $A
}

foo bla "hello ppl"

我希望输出为:
"bla" "你好人"

我需要做什么来代替省略号?

【问题讨论】:

  • 你想完成什么? foo 的输出是用作任何内容的输入,还是您只想要原始文本?
  • 它应该被用作另一个命令的输入(在这种情况下是邮件)。
  • @rubim:那么我认为你让它变得比需要的困难得多。 mail "$@" 将在没有取消解析/重新解析步骤的情况下给出结果。如果"$@" 的状态不正确,请展示您所拥有的。

标签: string bash shell concatenation


【解决方案1】:

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

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

foo bla "hello ppl"

【讨论】:

  • +1 此解决方案有效!我很懒,所以我通常会去掉 'in "$@"' 部分,只使用 'for i'
  • 我忘了在问题中提到这一点,但我的意思是不使用循环来做到这一点。正在寻找一些神奇的 bash 扩展或其他东西。
【解决方案2】:

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"

【讨论】:

    【解决方案3】:

    不需要循环:

    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"
    

    【讨论】:

      【解决方案4】:

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

      function foo() {
          A=("${@/#/\"}")
          A=("${A[@]/%/\"}")
          echo -e "${A[@]}"
      }
      
      foo bla "hello ppl" kkk 'ss ss'
      

      输出

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

      【讨论】:

        【解决方案5】:

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

        foo() { printf '"%s" ' "$@"; echo ""; }
        
        foo bla "hello ppl"
        # => "bla" "hello ppl"
        

        【讨论】:

        • 叮!你赢得大奖。巨型泰迪熊还是四英尺啤酒瓶硬币银行?
        • 为什么要添加 echo "";在末尾?是不是没必要。
        • 所以输出将以换行符结束。只是让它看起来不错,不会弄乱你的提示。我意识到用命令替换调用时没有必要
        • 谢谢它很好用。糟糕的是,没有一个简单的、一个班轮的 bash 版本。
        • 呃,我不是提供了“简单的一个班轮”吗?
        【解决方案6】:

        目前唯一在参数中尊重反斜杠和引号的解决方案:

        $ 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 有效,则识别以下序列:

        • \反斜杠
        • \警报(BEL)
        • \b 退格

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

        请注意,此示例不可在真实代码中重现:

        感谢接受的答案和Danny Hong answer 在“如何在双引号内转义双引号?”

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-14
          • 1970-01-01
          • 2014-09-10
          相关资源
          最近更新 更多