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
Concatenate all arguments and wrap them with double quotes
提问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 eval
pass, the extra quotes will probably screw things up. That is, ls "is a file"
will list the file is a file
while
但除非它正在经历另一次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.
将尝试列表"is
, a
以及file"
你可能不希望。
回答by Paused until further notice.
No loop required:
不需要循环:
foo() { local saveIFS=$IFS; local IFS='"'; local a="${*/#/ \"}"; echo "$a"\"; IFS=$saveIFS; }
Saving IFS
isn't necessary in this simple example, especially restoring it right before the function exits, due to the fact that local
is used. However, I included it in case other things are going into the function that a changed IFS
might 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 (\
, \b
backspace, ...) will indeed be interpreted by the receiving program, even if not displayed interpreted in the terminal output.
特殊字符(\
, \b
backspace, ...)确实会被接收程序解释,即使在终端输出中没有显示解释。
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 -e
instead of just echo
or printf
in 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: \b
is the backspace character, so it erases Y in the example.
注意:\b
是退格字符,因此它在示例中擦除了 Y。
Note that this example is not to be reproduced in real code:
请注意,此示例不应在实际代码中重现:
- It is very uncommon to concatenate arguments, always use positional parameterwhen possible.
bash -c
andscreen -X
DO accept several arguments so there's no need to use concatenation: see Can't seem to use bash -c option with arguments after the -c option string). Just beware of passing something for$0
when usingbash -c
.
- 连接参数非常罕见,尽可能使用位置参数。
bash -c
并且要screen -X
接受多个参数,因此无需使用串联:请参阅似乎无法在 -c 选项字符串之后使用带有参数的 bash -c 选项)。$0
在使用时要小心传递一些东西bash -c
。
Thanks to the accepted answer and Danny Hong answerin "How to escape double quote inside a double quote?"