【问题标题】:Assign ksh/bash array with awk用 awk 分配 ksh/bash 数组
【发布时间】:2011-09-30 17:28:07
【问题描述】:

我正在尝试将给定的行转换为数组,例如这一行:

我的第一个\t \t你好世界

到以下 ksh/bash 数组:

[0]="My first"
[1]=""
[2]="Hello world"

我的代码:

TAB=`printf '\011'`

query()
{
    echo "$1"|awk -F"$TAB" '
        { 
            for(i = 0; i < NF; i++)
                QueryArray[i]=$i
        }';
}

line=`head -n 1 myFile`
typeset -a QueryArray;
query "$line"
echo "Array length: ${#QueryArray[*]}"
echo "- " ${QueryArray[0]}
echo "- " ${QueryArray[1]}
echo "- " ${QueryArray[2]}

但不起作用,有什么建议吗?

谢谢。

【问题讨论】:

    标签: arrays bash awk ksh


    【解决方案1】:

    我有一个不理解 $'ANSI' 字符串的旧 ksh,所以:

    str2array () {
        typeset arrayname=$1
        typeset IFS=$2
        shift 2
        eval "set -A $arrayname \$*"
    }
    
    s="Hello        World"     # tabs entered literally with "Ctrl-V tab"
    str2array myarray " " "$s"     # another literal tab as 2nd parm
    typeset -i i=0
    while [[ $i -lt ${#myarray[@]} ]]; do
        printf "%d\t%s\n" $i "${myarray[$i]}"
        i=$(( i+1 ))
    done
    

    对于 bash:

    str2array () {
        local arrayname=$1
        local IFS=$2
        shift 2
        eval "$arrayname=( \$* )"
    }
    
    s=$'hello\t\tworld'
    str2array myarray $'\t' "$s"
    for (( i=0; i < ${#myarray[@]}; i++ )); do
        printf "%d\t%s\n" $i "${myarray[$i]}"
    done
    

    我得到了与 Arnaud 对 David 的评论相同的结果:使用“word\t\tword”,中间字段被删除。我没有看到使用不同的分隔符(例如冒号)。

    ksh

    空白解释
    参数和命令替换后的结果 扫描替换以查找字段分隔符 (在 IFS 中找到的)并分成不同的参数,其中 找到这样的字符。显式空参数 ( "" ) 或 ('') 被保留。 隐式空参数(那些结果 from 没有值的参数)被删除。

    狂欢

    分词
    ... Shell 将 IFS 的每个字符视为一个分隔符,并将 其他扩展为这些字符上的单词的结果。如果 IFS 未设置,或者它的值正好是&lt;space&gt;&lt;tab&gt;&lt;newline&gt;,默认值, 然后是&lt;space&gt;&lt;tab&gt;&lt;newline&gt;的序列在开头和 先前展开的结果的末尾被忽略,并且任何 不在开头或结尾的 IFS 字符序列用于 分隔单词。如果 IFS 的值不是默认值,则 空白字符空格和制表符的序列在 单词的开头和结尾,只要空格字符是 在 IFS 的值中(一个 IFS 空白字符)。中的任何字符 不是 IFS 空白的 IFS,以及任何相邻的 IFS 空白 字符,分隔一个字段。 IFS 空白字符序列 也被视为分隔符。如果 IFS 的值为空,则无字 发生分裂。

    【讨论】:

    • 好像被我屏蔽了,会接受你的回答,谢谢回复!
    【解决方案2】:
    query()
    {
        IFS=$'\t'
        ind=0       
        for i in $1 
            do 
              QueryArray[$ind]=$i 
              let "ind+=1" 
            done
        unset IFS
    
    }
    
    declare -A QueryArray;
    query "Hello        World" #Hello\t \tWorld
    echo "Array length: ${#QueryArray[*]}"
    echo "- " ${QueryArray[0]}
    echo "- " ${QueryArray[1]}
    echo "- " ${QueryArray[2]}
    

    【讨论】:

      【解决方案3】:

      在 KSH 中不起作用。

      您需要使用typeset 而不是declare,并使用function 关键字。否则,satyajit 的回答就可以了。

      Kornshellified 为你...

      function query
      {
          IFS=$'\t'
          ind=0
          for i in $1
          do
              QueryArray[$ind]=$i
              let "ind+=1"
          done
          unset IFS
      
      }
      
      typeset -a QueryArray #Actually this is optional in Kornshell
      query "Hello                World" #Hello\t \tWorld
      
      # What the heck? Might as well go all Korn: print vs. echo
      print "Array length: ${#QueryArray[*]}"
      print -- "- ${QueryArray[0]}"
      print -- "- ${QueryArray[1]}"
      print -- "- ${QueryArray[2]}"
      

      【讨论】:

      • 只有当你有一个介于 2 \t\t 之间的字符时它才有效,如果你有 Hello\t\tWorld,它只会返回一个数组长度为 2 而不是我期望的 3
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-01-29
      • 1970-01-01
      • 2014-03-19
      • 2016-01-27
      • 2018-02-19
      • 2011-05-02
      • 1970-01-01
      相关资源
      最近更新 更多