我有一个包含这些参数及其值的文件
# parameters.txt
VAR1 001
VAR2 aaa
VAR3 'Hello World'
和另一个文件这样配置
# example.conf
VAR1 = 020
VAR2 = kab
VAR3 = ''
当我想获取函数中的值时,我使用这个命令
while read p; do
VALUE=$(echo $p | awk '{print $2}')
done < parameters.txt
第一个参数抛出正确的值,但最后一个参数只得到 'Hello for the blank space,我的问题是如何获得整个 'Hello World' 值?
最佳答案
如果你能用bash
,就没必要用awk
:read
和shell parameter expansion可以结合起来解决你的问题:
while read -r name rest; do
# Drop the '= ' part, if present.
[[ $rest == '= '* ]] && value=${rest:2} || value=$rest
# $value now contains the line's value,
# but *including* any enclosing ' chars, if any.
# Assuming that there are no *embedded* ' chars., you can remove them
# as follows:
value=${value//\'/}
done < parameters.txt
read
默认情况下也通过空格将一行分成多个字段,例如 awk
,但与 awk
不同的是,它能够将行的剩余部分分配给变量,即 last 一个,如果指定的变量少于找到的字段;
read
的 -r
选项通常值得指定以避免意外解释 \
字符。在输入中。
至于您的解决方案尝试:
awk
不知道输入中的引号 - 默认情况下,它通过空格将输入分成多个字段,而不考虑引号。
因此,诸如 'Hello World'
的字符串被简单地分解为字段 'Hello
和 World'
。
但是,在您的情况下,您可以使用精心制作的 FS 值将每个输入行拆分为其键和值(FS 是输入字段分隔符,也可以通过选项 -F
进行设置;该命令再次假定为 bash
,这使用 <(...)
的时间,一个所谓的 process substitution 和 $'...'
,一个 ANSI C-quoted string ):
while IFS= read -r value; do
# Work with $value...
done < <(awk -F$'^[[:alnum:]]+ (= )?\'?|\'' '{ print $2 }' parameters.txt)
再次假设值不包含嵌入 '
个实例。
字段分隔符正则表达式 $'^[[:alnum:]]+ (= )?\'?|\''
拆分每一行,以便第二个字段 $2
包含值,如果有的话,将包含 '
个字符。
xargs
是标准实用程序中罕见的异常(exception),因为它确实理解单引号和双引号字符串(但也不支持用于嵌入 引号)。
因此,您可以利用 xargs
在将参数传递给指定命令时隐式去除引号的能力,默认为 echo
(再次假定为 bash
):
while read -r name rest; do
# Drop the '= ' part, if present.
[[ $rest == '= '* ]] && value=${rest:2} || value=$rest
# $value now contains the line's value, strippe of any enclosing
# single quotes by `xargs`.
done < <(xargs -L1 < parameters.txt)
xargs -L1
一次处理一个 ( 1
) 行 ( -L
) 并隐式调用 echo
并在每行上找到所有标记,并从单个标记中删除任何包含的引号。
关于linux - 如何在 linux 中传递带引号但带有空格的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36253364/