简体   繁体   English

使用 awk 分配 ksh/bash 数组

[英]Assign ksh/bash array with awk

I'm trying to transform a given line to an array, for example this line:我正在尝试将给定的行转换为数组,例如这一行:

My first\t \tHello world我的第一个\t \t你好世界

to the following ksh/bash array:到以下 ksh/bash 数组:

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

My code:我的代码:

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]}

but doesn't work, any suggestions?但不起作用,有什么建议吗?

Thanks.谢谢。

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]}

Doesn't work in KSH.在 KSH 中不起作用。

You need to use typeset instead of declare , and use the function keyword.您需要使用typeset而不是declare ,并使用function关键字。 Otherwise, satyajit 's answer works just fine.否则, satyajit的答案就可以了。

Kornshellified for you... 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]}"

I have an older ksh that does not understand $'ANSI' strings, so:我有一个不理解$'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

for bash:对于 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

I'm getting the same result ar Arnaud's comment to David: with "word\t\tword", the middle field is being dropped.我得到了与 Arnaud 对 David 的评论相同的结果:使用“word\t\tword”,中间字段被删除。 I don't see that with a different delimiter such as colon.我没有看到使用不同的分隔符(例如冒号)。

ksh克什

Blank Interpretation空白解释
After parameter and command substitution, the results of substitutions are scanned for the field separator characters (those found in IFS) and split into distinct arguments where such characters are found.在参数和命令替换之后,将扫描替换结果以查找字段分隔符(在 IFS 中找到的那些),并将其拆分为可以找到此类字符的不同 arguments。 Explicit null arguments ( "" ) or ('') are retained.保留显式 null arguments ("") 或 ('')。 Implicit null arguments (those resulting from parameters that have no values) are removed.隐式 null arguments(由没有值的参数产生的那些)被删除。

bash bash

Word Splitting分词
... The shell treats each character of IFS as a delimiter, and splits the results of the other expansions into words on these characters. ... shell 将 IFS 的每个字符视为分隔符,并将其他扩展的结果拆分为这些字符上的单词。 If IFS is unset, or its value is exactly <space><tab><newline> , the default, then sequences of <space> , <tab> , and <newline> at the beginning and end of the results of the previous expansions are ignored, and any sequence of IFS characters not at the beginning or end serves to delimit words.如果 IFS 未设置,或者它的值恰好是<space><tab><newline> (默认值),那么<space><tab><newline>的序列位于先前扩展结果的开头和结尾被忽略,并且任何不在开头或结尾的 IFS 字符序列都用于分隔单词。 If IFS has a value other than the default, then sequences of the whitespace characters space and tab are ignored at the beginning and end of the word, as long as the whitespace character is in the value of IFS (an IFS whitespace character).如果 IFS 的值不是默认值,则在单词的开头和结尾处忽略空格字符 space 和 tab 的序列,只要空格字符在 IFS 的值中(IFS 空格字符)。 Any character in IFS that is not IFS whitespace, along with any adjacent IFS whitespace characters, delimits a field. IFS 中不是 IFS 空白的任何字符,以及任何相邻的 IFS 空白字符,都会分隔一个字段。 A sequence of IFS whitespace characters is also treated as a delimiter .一系列 IFS 空白字符也被视为分隔符 If the value of IFS is null, no word splitting occurs.如果IFS的值为null,则不发生分词。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM