ksh SET - 数组读取问题

ksh SET - 数组读取问题

你好,我试图使用 ksh 脚本读取一行到数组。但是,当字段值中存在逗号时,它的某些值会在相邻数组元素中多次存储。怎么避免这种情况我的分隔符是~

输入

17~4~~~char~Y~\"[_a-zA-Z0-9\.]\+@[a-zA-Z0-9]\+\.[a-z]\{2,\}\"~40~email id

代码

while IFS= read -r line
  do
   
        if [ $n != 1 ]; then
                IFS="~"
  
                set -A star $line
                col_pos=${star[1]}
                col_patt=${star[6]}
                col_len=${star[7]}
                col_file_id=${star[0]}

$行的值

 17 4   char Y \"[_a-zA-Z0-9\.]\+@[a-zA-Z0-9]\+\.[a-z]\2\" \"[_a-zA-Z0-9\.]\+@[a-zA-Z0-9]\+\.[a-z]\\\" 40 email id

问题是模式 ("[_a-zA-Z0-9.]+@[a-zA-Z0-9]+.[az]\2") 在读取时重复,但在实际输入文件中模式字段被定义一次。

答案1

在:

set -A star $line

正如$line未引用的那样,您正在调用 split+glob 运算符。在这里,您确实需要分割部分,但不需要全局部分,因此您应该首先禁用它:

set -o noglob

正如@Isaac正确识别的那样,您这里的问题与通配无关,而是由 ksh (且仅 ksh1)除了通配之外完成的大括号扩展,但在禁用通配时也会被禁用。

set -A array x y z是将数组设置为整体的 ksh88 / pdksh 方法。较新版本的 ksh(包括 ksh93 和 mksh)已采用 zsh 样式array=(x y z)

使用set -A语法,您需要:

set -A array -- values

(除了在 zsh 中不模拟 ksh 时),否则,如果第一个值以-或开头,它将无法正常工作+

所以:

set -o noglob; IFS='~'
while IFS= read -r line
do
  if [ "$n" != 1 ]; then
    set -A star -- $line
    col_pos=${star[1]}
    col_patt=${star[6]}
    col_len=${star[7]}
    col_file_id=${star[0]}

虽然在这里,我会避免所有这些问题并使用这个标准sh语法:

while IFS='~' read -r col_file_id col_pos x x x x col_patt col_len x
do
  if [ "$n" != 1 ]; then

¹ 除非在 mksh 和某些最新版本的 ksh93 中启用了 POSIX 模式,或者在编译时完全禁用了大括号扩展

答案2

问题:

  1. 该脚本不完整(缺少完成、缺少 fi 等)。
  2. 变量应该被引用(默认情况下总是)。

但您的主要问题在于大括号表达式{2,},它将在 之前重复字符串并以 结尾,2并且nothing在 中扩展时set -A star $line

一个未引用的 $line将进行多次扩展,其中之一是大括号扩展{,}

要分割字符串,而不将其不加引号地展开,使用~作为分隔符并将值放入数组中,这可能有效:

while IFS= read -r onestar; do star+=("$onestar"); done <<<"${line//~/$'\n'}"

假设line只有一行(不包含换行符),它应该,不应该吗?

相关内容