string 连接所有参数并用双引号括起来

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3104209/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 00:47:09  来源:igfitidea点击:

Concatenate all arguments and wrap them with double quotes

stringbashshellconcatenation

提问by rui

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

foo bla "hello ppl"

I would like the output to be:
"bla" "hello ppl"

我希望输出为:
“bla”“hello ppl”

What do I need to do instead of the ellipsis?

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

回答by glenn Hymanman

@msw has the right idea (up in the comments on the question). However, another idea to print arguments with quotes: use the implicit iteration of printf:

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

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

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

回答by Fritz G. Mehner

Use parameter substitution to add " as prefix and suffix:

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

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

foo bla "hello ppl" kkk 'ss ss'

Output

输出

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

回答by ninjalj

You can use "$@" to treat each parameter as, well, a separate parameter, and then loop over each parameter:

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

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

foo bla "hello ppl"

回答by msw

ninjalj had the right idea, but the use of quotes was odd, in part because what the OP is asking for is not really the best output format for many shell tasks. Actually, I can't figure out what the intended task is, but:

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

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

puts its quoted arguments one per line which is usually the best way to feed other programs. You do get output in a form you didn't ask for:

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

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

but it can be easily converted and this is the idiom that most shell invocations would prefer:

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

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

but unless it is going through another evalpass, the extra quotes will probably screw things up. That is, ls "is a file"will list the file is a filewhile

但除非它正在经历另一次eval传递,否则额外的引号可能会把事情搞砸。也就是说,ls "is a file"将列出文件,is a file

$ ls `quote_args is\ a\ file`

will try to list "is, a, and file"which you probably don't want.

将尝试列表"isa以及file"你可能不希望。

回答by Paused until further notice.

No loop required:

不需要循环:

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

Saving IFSisn't necessary in this simple example, especially restoring it right before the function exits, due to the fact that localis used. However, I included it in case other things are going into the function that a changed IFSmight affect.

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

Example run:

示例运行:

$ 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"

回答by KrisWebDev

The only solution at this time that respects backslashes and quotes inside the argument:

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

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

Notice the "%q"" "

注意“%q”“”

%qARGUMENT is printed in a format that can be reused as shell input, escaping non-printable characters with the proposed POSIX $'' syntax.

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

Special characters (\, \bbackspace, ...) will indeed be interpreted by the receiving program, even if not displayed interpreted in the terminal output.

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

Let's test:

让我们测试一下:

# display.sh: Basic script to display the first 3 arguments passed
echo -e '#!/bin/bash'"\n"'echo -e "$1="""; echo -e "$2="""; echo -e "$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

More complicate test:

更复杂的测试:

./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:\\\-"

In display.sh, we are using echo -einstead of just echoor printfin order to interpret the special characters. This is only representative if your called program interprets them.

display.sh中,我们使用echo -e,而不是仅仅echo还是printf以解释的特殊字符。这仅在您被调用的程序解释它们时才具有代表性。

-eenable interpretation of backslash escapes

If -e is in effect, the following sequences are recognized:

  • \ backslash
  • \a alert (BEL)
  • \b backspace
  • Etc.

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

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

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

NB: \bis the backspace character, so it erases Y in the example.

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

Note that this example is not to be reproduced in real code:

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

Thanks to the accepted answer and Danny Hong answerin "How to escape double quote inside a double quote?"

感谢接受的答案和丹尼洪在“如何在双引号中转义双引号?”中的答案