使用 awk 分配 ksh/bash 数组

发布于 2024-11-19 11:39:51 字数 584 浏览 3 评论 0原文

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

我的第一个\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]}

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

谢谢。

I'm trying to transform a given line to an array, for example this line :

My first\t \tHello world

to the following ksh/bash array:

[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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风流物 2024-11-26 11:39:52

我有一个较旧的 ksh,它不理解 $'ANSI' 字符串,因此:

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=

我得到了相同的结果 ar Arnaud 对 David 的评论:使用“word\t\tword”,中场正在被放弃。我没有看到使用不同的分隔符(例如冒号)的情况。

克什

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

bash

分词
...
shell 将 IFS 的每个字符视为分隔符,并将
这些字符的其他扩展为单词的结果。如果IFS
未设置,或者其值恰好是 ,默认值,
然后是开头的 序列,
先前扩展结果的末尾将被忽略,并且任何
不在开头或结尾的 IFS 字符序列用于
界定单词。如果 IFS 的值不是默认值,则
空白字符 space 和 tab 的序列将被忽略
单词的开头和结尾,只要空格字符是
在 IFS 的值中(IFS 空白字符)。中的任意字符
不是 IFS 空白的 IFS 以及任何相邻的 IFS 空白
字符,分隔字段。 IFS 空白字符序列
也被视为分隔符
。如果IFS的值为空,则没有字
发生分裂。

hello\t\tworld' str2array myarray

我得到了相同的结果 ar Arnaud 对 David 的评论:使用“word\t\tword”,中场正在被放弃。我没有看到使用不同的分隔符(例如冒号)的情况。

克什

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

bash

分词
...
shell 将 IFS 的每个字符视为分隔符,并将
这些字符的其他扩展为单词的结果。如果IFS
未设置,或者其值恰好是 ,默认值,
然后是开头的 序列,
先前扩展结果的末尾将被忽略,并且任何
不在开头或结尾的 IFS 字符序列用于
界定单词。如果 IFS 的值不是默认值,则
空白字符 space 和 tab 的序列将被忽略
单词的开头和结尾,只要空格字符是
在 IFS 的值中(IFS 空白字符)。中的任意字符
不是 IFS 空白的 IFS 以及任何相邻的 IFS 空白
字符,分隔字段。 IFS 空白字符序列
也被视为分隔符
。如果IFS的值为空,则没有字
发生分裂。

\t' "$s" for (( i=0; i < ${#myarray[@]}; i++ )); do printf "%d\t%s\n" $i "${myarray[$i]}" done

我得到了相同的结果 ar Arnaud 对 David 的评论:使用“word\t\tword”,中场正在被放弃。我没有看到使用不同的分隔符(例如冒号)的情况。

克什

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

bash

分词
...
shell 将 IFS 的每个字符视为分隔符,并将
这些字符的其他扩展为单词的结果。如果IFS
未设置,或者其值恰好是 ,默认值,
然后是开头的 序列,
先前扩展结果的末尾将被忽略,并且任何
不在开头或结尾的 IFS 字符序列用于
界定单词。如果 IFS 的值不是默认值,则
空白字符 space 和 tab 的序列将被忽略
单词的开头和结尾,只要空格字符是
在 IFS 的值中(IFS 空白字符)。中的任意字符
不是 IFS 空白的 IFS 以及任何相邻的 IFS 空白
字符,分隔字段。 IFS 空白字符序列
也被视为分隔符
。如果IFS的值为空,则没有字
发生分裂。

I have an older ksh that does not understand $'ANSI' strings, so:

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:

str2array () {
    local arrayname=$1
    local IFS=$2
    shift 2
    eval "$arrayname=( \$* )"
}

s=

I'm getting the same result ar Arnaud's comment to David: with "word\t\tword", the middle field is being dropped. 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. Explicit null arguments ( "" ) or
('') are retained. Implicit null arguments (those resulting
from parameters that have no values) are removed.

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. 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. 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). Any character in
IFS that is not IFS whitespace, along with any adjacent IFS whitespace
characters, delimits a field. A sequence of IFS whitespace characters
is also treated as a delimiter
. If the value of IFS is null, no word
splitting occurs.

hello\t\tworld' str2array myarray

I'm getting the same result ar Arnaud's comment to David: with "word\t\tword", the middle field is being dropped. 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. Explicit null arguments ( "" ) or
('') are retained. Implicit null arguments (those resulting
from parameters that have no values) are removed.

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. 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. 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). Any character in
IFS that is not IFS whitespace, along with any adjacent IFS whitespace
characters, delimits a field. A sequence of IFS whitespace characters
is also treated as a delimiter
. If the value of IFS is null, no word
splitting occurs.

\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. 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. Explicit null arguments ( "" ) or
('') are retained. Implicit null arguments (those resulting
from parameters that have no values) are removed.

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. 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. 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). Any character in
IFS that is not IFS whitespace, along with any adjacent IFS whitespace
characters, delimits a field. A sequence of IFS whitespace characters
is also treated as a delimiter
. If the value of IFS is null, no word
splitting occurs.

魔法少女 2024-11-26 11:39:52
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]}
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]}
素染倾城色 2024-11-26 11:39:52

在 KSH 中不起作用。

您需要使用 typeset 而不是 declare,并使用 function 关键字。否则, satyajit 的答案就很好。

科恩壳为您化...

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

Doesn't work in KSH.

You need to use typeset instead of declare, and use the function keyword. Otherwise, satyajit's answer works just fine.

Kornshellified for you...

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]}"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文