5

我想使用从文件中读取的参数执行命令。这工作正常,直到 1 个参数需要有一个空格。

我试过用引号和反斜杠对单词进行分组,但都没有奏效。

我所追求的功能正是这样xargs做的,除了我需要调用一个函数而不是一个命令,因为它依赖于脚本中其他地方设置的其他变量

脚本:

do_echo() {
    echo '$1:' $1
    echo '$2:' $2
}
line=`cat input.txt` #cat used for simplicity, can have more than 1 line
do_echo $line

输入.txt:

"hello world" "hello back"

预期结果:

$1: hello world
$2: hello back

观察结果:

$1: "hello
$2: world"

编辑:

我正在使用它以不同的输入多次执行相同的命令。每行最多有 15 个参数,可能超过 50 行。

表格格式将是理想的,尽管将每个参数放在一行中的当前答案将起作用。

4

2 回答 2

4

未加引号的变量(如do_echo $line)在变量中的任何字符处严格分割IFS(默认设置为制表符、空格、换行符)。严格意味着非常严格,没有办法引用或逃避分裂。

基本的解决方法是将一个不需要的字符(例如冒号:)定义为拆分字符。

例如

$ cat input.txt
hello world:hello back
$ line=$(head -n 1 input.txt)
$ OLDIFS=$IFS IFS=:
$ do_echo $line
$1: hello world
$2: hello back
$ IFS=$OLDIFS

另一种解决方法是使用evaleval很危险。你绝对必须相信输入!

$ cat input.txt
"hello world" "hello back"
$ line=$(head -n 1 input.txt)
$ eval do_echo "$line"
$1: hello world
$2: hello back
于 2012-08-24T14:43:47.207 回答
3

不要使用引号,而是使用保证不会出现在单个参数中的字符来分隔每个参数。例如,使用分号:

hello world;hello back
argument 1;argument 2

然后你可以读取一组参数,一次一批,使用read

while IFS=';' read -a arguments; do
    do_echo "${arguments[@]}"
done < input.txt

如果您可以在文件中输入模糊的 ASCII 控制字符,例如单位分隔符 (ASCII 0x1f),则它们不太可能出现在参数中。

于 2012-08-24T14:21:09.580 回答