1

我尝试编写 KSH 脚本来处理由名称-值对组成的文件,每行有几个。

格式为:

NAME1 VALUE1,NAME2 VALUE2,NAME3 VALUE3, etc

假设我写:

read l
IFS=","
set -A nvls $l
echo "$nvls[2]"

这将给我第二个名称-值对,既好又简单。现在,假设任务已扩展,因此值可以包含逗号。他们应该被逃脱,像这样:

NAME1 VALUE1,NAME2 VALUE2_1\,VALUE2_2,NAME3 VALUE3, etc

显然,我的代码不再有效,因为“读取”会删除所有引用,并且数组的第二个元素将只是“NAME2 VALUE2_1”。

我被没有“read -A array”的旧 ksh 卡住了。我用“read -r”和“eval set -A ....”尝试了各种技巧,但无济于事。我不能使用“read nvl1 nvl2 nvl3”在读取中进行转义和拆分,因为我事先不知道每行中有多少个名称-值对。

有人对我有用吗?

PS 我知道我在 Perl、Python 甚至 awk 中都在短时间内完成了这项工作。但是,我必须在 ksh 中执行此操作(...或死去尝试;)

4

2 回答 2

1

正如经常发生的那样,我在公共论坛提出问题后几分钟就得到了答案:(

我通过以下 sed 脚本管道输入文件来解决引用/取消引用问题:

sed -e 's/\([^\]\),/\1\
/g;s/$/\
/

它将输入转换为:

NAME1.1 VALUE1.1
NAME1.2 VALUE1.2_1\,VALUE1.2_2
NAME1.3 VALUE1.3
<empty line>
NAME2.1 VALUE2.1
<second record continues>

现在,我可以像这样解析这个输入:

while read name value ; do
  echo "$name => $value"
done

值的逗号将不被“读取”引用,如果我愿意,我可以将“名称”和“值”填充到某个关联数组中。

PS既然我不能接受自己的答案,我应该删除问题,还是......?

于 2008-10-05T13:06:03.093 回答
0

您还可以将\,模式更改为其他已知不会出现在任何字符串中的模式,然后在将输入拆分为数组后将其更改回来。您可以使用 ksh 内置模式替换语法来执行此操作,您不需要使用 sed 或 awk 或任何东西。

read l
l=${l//\\,/!!}
IFS=","
set -A nvls $l
unset IFS
echo ${nvls[2]/!!/,}
于 2008-10-30T02:54:06.837 回答