用文件输入在bash中分词

时间:2011-02-03 07:26:02

标签: parsing bash arguments

我在使用bash解析命令行中的单词时遇到了一些麻烦。我觉得最容易举一个例子,所以不用多说,我们走了。

这是脚本test.sh:

#!/bin/bash
echo "inside test with $# arguments"

if [[ $# -eq 0 ]] then data=cat data.txt echo ./test $data ./test $data else for arg in "$@" do echo "Arg is \"$arg\"" done fi

这是文件data.txt:

cat data.txt

所需的输出

"abc 123" 1 2 3 "how are you"

$ test.sh

但相反,我得到了


inside test with 0 arguments
./test "abc 123" 1 2 3 "how are you"
inside test with 5 arguments
Arg is "abc 123"
Arg is "1"
Arg is "2"
Arg is "3"
Arg is "how are you"

真正烦人的是,如果我执行从test.sh的第7行转储的命令,我得到所需的输出(当然没有前两行)。

所以从本质上说,如果给定的输入已经从文件中读取,有没有办法让bash解析单词?

3 个答案:

答案 0 :(得分:1)

您可以使用eval

eval ./test "$data"

must be careful知道在使用eval时可以信任该文件的内容。要说明原因,请在数据文件的行末添加; pwd。运行脚本时,将打印当前目录。想象一下,如果它是破坏性的东西。

如果您可以选择数据文件中字段之间的空格以外的分隔符,那可能会更好。例如,如果您使用制表符,则可以执行以下操作:

while IFS=$'\t' read -r -a array
do
    for item in "${array[@]}"
    do
        something with "$item"
    done
done < data.txt

您不需要引用包含空格的字段。

这是对我认为是你问题中的拼写错误的更正:

data=$(cat data.txt)

答案 1 :(得分:1)

无需两次调用脚本。

如果您发现没有参数,可以使用set将其更改为其他参数,例如:

#!/bin/bash

if [ $# -eq 0 ]
then
    echo "inside test with $# arguments"
    eval set -- $(<data.txt)
fi

echo "inside test with $# arguments"
for arg in "$@"
do
    echo "Arg is \"$arg\""
done

答案 2 :(得分:0)

是的,只需替换

./test $data

eval ./test $data