我编写了一个小型 shell 脚本来从文本文件中获取一些值,并将它们放入 for 循环中以将它们用作变量,我将使用这些值作为 wsadmin 命令的输入。下面是我写的shell脚本。
FILE=`cat test.txt`
for i in `echo "$FILE"`
do
DS_NAME=`echo "$i"|awk -F"=" '{print $2}'`
HOST_NAME=`echo "$i"|awk -F"=" '{print $2}'`
PORT_NUMBER=`echo "$i"|awk -F"=" '{print $3}'`
DB_NAME=`echo "$i"|awk -F"=" '{print $4}'`
echo "$DS_NAME"
echo "$HOST_NAME"
echo "$PORT_NUMBER"
echo "$DB_NAME"
done
我的 test.txt 文件的内容如下。
test connection data source=test.connect.com=1234=testdb
test connection data source=test1.connect.com=1134=test1db
test connection data source=test2.connect.com=1234=test2db
当我执行 shell 脚本时,我正在寻找如下所示的输出。
test connection data source
test1.connect.com
1234
testdb
但不幸的是,我没有得到我需要的东西,我相信这是因为 DS_NAME 中的单词之间存在空格。我该如何解决这个问题?有什么建议请。
答案1
FILE=`cat test.txt`
将文件的内容(尾随换行符除外)存储在变量 中FILE
。然后echo "$FILE"
打印文件内容(假设它不以破折号开头并且不包含任何反斜杠)。直接写会更简单
for i in `cat test.txt`
接下来,允许分词的上下文中的命令替换`…`
将命令的输出分解为单词,而不是行。 (这是默认设置,可以更改,尽管这不是解决问题的最佳方法。)这是您可见的问题:循环为每个单词运行一次,而不是每行运行一次。此外,这些单词被视为 shell 通配符模式:如果有像 之类的行test * source=a=b=c
,*
将会被当前目录中的文件名列表替换。
使用 awk 从行中提取字段是可行的(除了来自 的损坏echo
),但它过于复杂且缓慢。
有一个 shell 内置函数可以读取一行并将其拆分为多个字段:read
。就用那个吧。要使用字符作为字段分隔符,请设置命令的=
变量。传递该选项,除非您想将行末尾的反斜杠视为指示连续行。IFS
read
-r
read
while IFS='=' read -r DS_NAME HOST_NAME PORT_NUMBER DB_NAME ignored; do
…
done <test.txt
额外的变量ignored
使您的解析器在存在额外字段的情况下更加健壮,例如
test connection data source=test.connect.com=1234=testdb=hey, a new field