用空格向bash函数传递字符串
我有一行是从文件中读到的用空格向bash函数传递字符串,bash,quotes,Bash,Quotes,我有一行是从文件中读到的 line="1 \"Some Text Here\"" 和一个接受两个参数的函数 print() { echo $1 echo $2 } 当我执行 print $line 我得到的输出是 1 "Some 我想要的是 1 Some Text Here 您需要使用变量IFS。在脚本类型中IFS=\”。这应该可以解决您的问题。您需要在脚本类型中IFS=\”使用变量IFS。这应该可以解决您的问题。如果您信任输入,可以使用eval(通常要避免,因为恶意输
line="1 \"Some Text Here\""
和一个接受两个参数的函数
print() {
echo $1
echo $2
}
当我执行
print $line
我得到的输出是
1
"Some
我想要的是
1
Some Text Here
您需要使用变量
IFS
。在脚本类型中IFS=\”
。这应该可以解决您的问题。您需要在脚本类型中IFS=\”
使用变量IFS
。这应该可以解决您的问题。如果您信任输入,可以使用eval
(通常要避免,因为恶意输入字符串可能会做不必要的事情):
但是,即使使用无害的输入字符串,eval
命令也会在输入字符串包含所谓的shell元字符时中断;()<>
此外,如果字符串碰巧包含类似路径名模式(glob)的标记,例如*
,它们会在不经意间被扩展;相关的模式字符是:*?[]
因此,为了使上述内容更加健壮,使用\
输入字符串中的转义模式字符和元字符如下所示:
eval print "$(sed 's/[][*?&;()<>]/\\&/g' <<<"$line")"
结果:
[1]
[double-quoted string]
[*]
[single-quoted string]
[string-with-;|>-(metachars)]
注意事项和限制:
#!/usr/bin/env bash
# Sample function that prints each argument passed to it separately
print() {
for arg; do
echo "[$arg]" # enclose value in [] to better see its boundaries
done
}
# Sample input string with embedded quoted strings, an unqoted
# glob-like string, and an string containing shell metacharacters
line="1 \"double-quoted string\" * 'single-quoted string' string-with-;|>-(metachars)"
# Let `xargs` split the string into lines (-n 1) and read the
# result into a bash array (read -ra).
# This relies on `xargs`' ability to recognize quoted strings embedded
# in a string literal.
IFS=$'\n' read -d '' -ra args <<<"$(xargs -n 1 printf '%s\n' <<<"$line")"
# Now pass the array to the `print` function.
print "${args[@]}"
- 无引号标记允许使用
转义嵌入字符,如空格、单引号和双引号\
- 但是,其他字符前面的
也会被忽略,这可能是不需要的;e、 g.:\
-使用echo'a\b'| xargs#->'ab'
,或者使用单引号或双引号代替标记\
- 但是,其他字符前面的
- 带引号的令牌不需要内部转义,但遗憾的是,不支持嵌入相同类型的引号-转义似乎不起作用
- 请注意,通常不需要指定
作为printf“%s\n”
执行的命令,因为xargs
默认调用xargs
实用程序(而不是shell内置);但是,一些echo
实现识别自己的选项,例如echo
(但不支持-e
),因此第一个输出标记可能会被误认为是选项。--
相比之下,
在所有情况下都有效printf“%s\n
- 不支持包含嵌入换行符的带引号的字符串。(
在这种情况下报告了一个解析错误)-据推测,这很少会成为问题xargs
eval
(通常要避免,因为恶意输入字符串可能会做不必要的事情):
但是,即使使用无害的输入字符串,eval
命令也会在输入字符串包含所谓的shell元字符时中断;()<>
此外,如果字符串碰巧包含类似路径名模式(glob)的标记,例如*
,它们会在不经意间被扩展;相关的模式字符是:*?[]
因此,为了使上述内容更加健壮,使用\
输入字符串中的转义模式字符和元字符如下所示:
eval print "$(sed 's/[][*?&;()<>]/\\&/g' <<<"$line")"
结果:
[1]
[double-quoted string]
[*]
[single-quoted string]
[string-with-;|>-(metachars)]
注意事项和限制:
#!/usr/bin/env bash
# Sample function that prints each argument passed to it separately
print() {
for arg; do
echo "[$arg]" # enclose value in [] to better see its boundaries
done
}
# Sample input string with embedded quoted strings, an unqoted
# glob-like string, and an string containing shell metacharacters
line="1 \"double-quoted string\" * 'single-quoted string' string-with-;|>-(metachars)"
# Let `xargs` split the string into lines (-n 1) and read the
# result into a bash array (read -ra).
# This relies on `xargs`' ability to recognize quoted strings embedded
# in a string literal.
IFS=$'\n' read -d '' -ra args <<<"$(xargs -n 1 printf '%s\n' <<<"$line")"
# Now pass the array to the `print` function.
print "${args[@]}"
- 无引号标记允许使用
转义嵌入字符,如空格、单引号和双引号\
- 但是,其他字符前面的
也会被忽略,这可能是不需要的;e、 g.:\
-使用echo'a\b'| xargs#->'ab'
,或者使用单引号或双引号代替标记\
- 但是,其他字符前面的
- 带引号的令牌不需要内部转义,但遗憾的是,不支持嵌入相同类型的引号-转义似乎不起作用
- 请注意,通常不需要指定
作为printf“%s\n”
执行的命令,因为xargs
默认调用xargs
实用程序(而不是shell内置);但是,一些echo
实现识别自己的选项,例如echo
(但不支持-e
),因此第一个输出标记可能会被误认为是选项。--
相比之下,
在所有情况下都有效printf“%s\n
- 不支持包含嵌入换行符的带引号的字符串。(
在这种情况下报告了一个解析错误)-据推测,这很少会成为问题xargs
shift
可能适合您
例如:
print() {
echo "$1"
shift
echo "$*"
}
这将打印第一个参数,移动参数列表(删除第一个参数),然后打印其余参数
这应该会给你这个结果:
$ text="1 \"Multiple Words Here\""
$ print() {
> echo "$1"
> shift
> echo "$*"
> }
$ print $text
1
"Multiple Words Here"
根据您的具体情况,使用
shift
可能适合您
例如:
print() {
echo "$1"
shift
echo "$*"
}
这将打印第一个参数,移动参数列表(删除第一个参数),然后打印其余参数
这应该会给你这个结果:
$ text="1 \"Multiple Words Here\""
$ print() {
> echo "$1"
> shift
> echo "$*"
> }
$ print $text
1
"Multiple Words Here"
文件格式似乎对引号在
bash
中的工作方式做出了错误的假设。如果可能,将文件更改为使line
成为一个数组:line=(1“此处有一些文本”)
。这在从文件读取的行上下文中是否有意义。如果文件中有这样的行格式,会让excel发疯,那么您如何定义bash
变量line
?您显示的行不是有效的bash
赋值语句(不允许等号周围有空格)。我假设这是一个输入错误,而你只是在寻找文件的来源。文件格式似乎对引号在bash
中的工作方式做出了错误的假设。如果可能,将文件更改为使line
成为一个数组:line=(1“此处有一些文本”)
。这在从文件读取的行上下文中是否有意义。宁愿