linux - 如何在 linux 中传递带引号但带有空格的参数

标签 linux shell awk scripting

我有一个包含这些参数及其值的文件

# 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:readshell 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' 的字符串被简单地分解为字段 'HelloWorld'

但是,在您的情况下,您可以使用精心制作的 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/

相关文章:

python - 在 Python 中复制和移动文件?

linux - 检查进程的状态并在 unix 中完成时启动另一个脚本

arrays - 检查 awk 数组是否包含值

linux - 在 Linux 上删除除 .git 目录和 .gitignore 之外的所有内容

c - 如何打开覆盖现有内容的文件

linux - 如何在linux中使用grep查找所有包含特定命令的文件?

linux - csh shell 脚本故障排除

linux - 如何使用 sed 或 awk 命令根据另外两个变量的值设置一个变量

perl - 在可变长度文件名中使用 bash 排序命令

php - 使用 mv 重命名 php 中的符号链接(symbolic link)