内联数组替换

时间:2018-08-17 21:20:45

标签: bash

我有几行file

x 1
y 2
z 3 t

我需要将每一行作为参数传递给某个程序:

$ program "x 1" "y 2" "z 3 t"

我知道如何使用两个命令来做到这一点:

$ readarray -t a < file
$ program "${a[@]}"

我该如何使用一个命令?像这样:

$ program ??? file ???

2 个答案:

答案 0 :(得分:1)

readarray命令的(默认)选项表明您的file项用换行符分隔。

因此,为了在 one 命令中实现所需的功能,您可以利用特殊的IFS变量来对单词进行拆分。换行符(例如,参见this doc),并用无引号的命令替换来调用program

IFS=$'\n'; program $(cat file)

如@CharlesDuffy所建议:

  1. 您可能希望通过预先运行set -f来禁用globbing,如果要将这些修改保留在本地,则可以将整个内容包含在一个子shell中:

    ( set -f; IFS=$'\n'; program $(cat file) )
    
  2. 为避免parens和/bin/cat进程的性能损失,您可以改为:

    ( set -f; IFS=$'\n'; exec program $(<file) )
    

    其中$(<file)Bash equivalent$(cat file)的位置(更快,因为它不需要分叉/bin/cat),而exec使用由创建的子shell父母。

    但是,请注意,如果exec不是PATH中的真实程序,则program技巧将无法使用(也就是说,如果exec: program: not found program只是脚本中定义的函数)。

答案 1 :(得分:0)

传递一组参数应该更有条理: 在此示例中,我正在寻找一个包含chk_disk_issue = something等的文件。因此,我通过读取作为参数传入的配置文件来设置值。

# -- read specific variables from the config file (if found) --
if [ -f "${file}" ] ;then
    while IFS= read -r line ;do
        if ! [[ $line = *"#"* ]]; then
            var="$(echo $line | cut -d'=' -f1)"
            case "$var" in
                chk_disk_issue)
                    chk_disk_issue="$(echo $line | tr -d '[:space:]' | cut -d'=' -f2 | sed 's/[^0-9]*//g')"
                ;;
                chk_mem_issue)
                    chk_mem_issue="$(echo $line | tr -d '[:space:]' | cut -d'=' -f2 | sed 's/[^0-9]*//g')"
                ;;
                chk_cpu_issue)
                    chk_cpu_issue="$(echo $line | tr -d '[:space:]' | cut -d'=' -f2 | sed 's/[^0-9]*//g')"
                ;;
            esac
        fi
    done < "${file}"
fi

如果这些不是参数,则为脚本找到一种将其作为脚本内部数据读取并传递文件名的方法。