将字符串直接拆分成数组

6
假设我想将一个字符串传递给awk,以便在按模式(pattern)拆分后,子字符串成为关联数组的索引(而不是值)。

就像这样:

$ awk -v s="A:B:F:G" 'BEGIN{ # easy, but can these steps be combined?
                            split(s,temp,":")  # temp[1]="A",temp[2]="B"...
                            for (e in temp) arr[temp[e]] #arr["A"], arr["B"]...
                            for (e in arr) print e 
                            }'
A
B
F
G

有没有awkism或gawkism可以直接将字符串s分割成其组件,并使这些组件成为arr中的索引项?


原因是(更大的图像)我想要这样的东西(伪awk):

awk -v s="1,4,55" 'BEGIN{[arr to arr["1"],arr["5"],arr["55"]} $3 in arr {action}'
3个回答

4

没有比以下方法更好的将分隔的子字符串映射到数组索引的方式:

split(str,tmp); for (i in tmp) arr[tmp[i]]

如果您不喜欢使用上述方法来完成您的最终伪代码所做的事情:

FWIW
awk -v s="1,4,55" 'BEGIN{split(s,tmp,/,/); for (i in tmp) arr[tmp[i]]} $3 in arr{action}'

那么获得相同行为的另一种方法是:
awk -v s=",1,4,55," 'index(s,","$3","){action}'

1
我认为split(str,tmp); for (i in tmp) arr[tmp[i]]可能是正确的做法。谢谢! - dawg
为了避免第二种解决方案中的 s 的分隔符丢失,我建议使用以下 awk -v s="A:B:C:G" 's ~ "(^|:)" $3 "(:|$)"{action}' - NeronLeVelu
1
@NeronLeVelu 这将其转换为正则表达式比较,因此您需要担心字符串中的正则表达式元字符。原始代码使用字符串比较($3 in arr),我发布的代码也是使用index()进行的,因此正则表达式元字符只会被视为字面值。 - Ed Morton
1
好的,我忘记假设那一部分了,你指出这个可能是个问题。 - NeronLeVelu

1

这可能是无用且不必要地复杂,但我会使用 whilematchsubstr 打开游戏:

$ awk -v s="A:B:F:G" '
BEGIN {
    while(match(s,/[^:]+/)) {
        a[substr(s,RSTART,RLENGTH)]
        s=substr(s,RSTART+RLENGTH)
    }
    for(i in a)
        print i
}'
A
B
F
G

我渴望看到一些有用的解决方案(如果有的话)。我尝试着玩弄了一下asort等函数。

1

其他方式的 awkism

cat file

1 hi
2 hello
3 bonjour
4 hola
5 konichiwa

运行它,

awk 'NR==FNR{d[$1]; next}$1 in d' RS="," <(echo "1,2,4") RS="\n" file

你得到了,

1 hi
2 hello
4 hola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接