Awk将字符串拆分为单词和数字

5

我正在尝试在字母和数字之间进行分隔,但使用预测失败的解决方案:

echo 50cats30dogs100squirrels | awk '{split($0,a,/(?<=\D)(.*)(?=\d)/); print a[1],a[2],a[3]}'

awk: illegal primary in regular expression (?<=\D)(.*)(?=\d) at <=\D)(.*)(?=\d)
 source line number 1
 context is
     >>> {split($0,a,/(?<=\D)(.*)(?=\d)/) <<<

有没有其他方法可以在Awk中完成这个操作?
编辑:
抱歉之前表述不够清晰。期望的输出结果只需要像这样添加空格:
50 cats 30 dogs 100 squirrels

你可以看一下这个问题。总结一下,awk没有后顾正则表达式。 - David784
awk 不支持向前或向后查找,如果您在问题中提供样本输入和输出,我们可以更清楚地了解情况并尝试在这里提供帮助,谢谢。 - RavinderSingh13
数组 a 应该包含什么内容?我不确定你是想要数字还是单词。 - glenn jackman
1
关于您的编辑:什么?50cats30dogs100squirrels -> 50 cats 30 dogs 100 squirrels 实际上是 2S5M1I^ATAG1I3M1D5M -> SSMMMMMI^^^^IMMMDMMMMM - James Brown
我认为这只是一个玩具示例(或解决更复杂问题的一步)。我会发一个新问题。 - Lechu
显示剩余4条评论
5个回答

5

仅根据您提供的示例,如果这正是您要寻找的内容,请尝试以下方法。此代码已在GNU awk中编写和测试(我相信它应该可以在任何awk中使用)。

echo "50cats30dogs100squirrels" | awk '{gsub(/[^0-9]+/," & ")} 1'

以下是所示样例的输出结果:
50 cats 30 dogs 100 squirrels

5

有没有其他方法可以使用AWK完成这个任务?

我将使用GNU AWK 完成此任务,假设file.txt的内容为

50cats30dogs100squirrels

那么

awk 'BEGIN{FPAT="([[:alpha:]]+)|([[:digit:]]+)"}{$1=$1;print}' file.txt

输出

50 cats 30 dogs 100 squirrels

解释:我使用FPAT指导AWK,使其识别包含一个或多个字母或数字的列。然后我执行$1=$1以重新构建字符串(如果没有$1=$1;,输出将与输入相同),并将其print出来。

(在gawk 4.2.1中测试过)


这很有趣!它只能应用于特定的领域吗?可以使用分隔符或更好的方法将其存储在数组中吗? - Lechu
@LechKaczmarczyk,无法同时使用FSFPAT,更准确地说,将值分配给FPAT会覆盖使用FS和FIELDWIDTHS进行字段拆分。 https://www.gnu.org/software/gawk/manual/html_node/Splitting-By-Content.html 您可以使用patsplit函数将提取的元素存储到数组中,如https://www.gnu.org/software/gawk/manual/html_node/String-Functions.html所述。 - Daweo

3

(?<=\D)(.*)(?=\d)是一个PCRE。根据POSIX标准定义,没有强制性的Unix工具支持PCRE。特别地,awk支持ERE。

使用GNU awk的FPAT:

$ echo '50cats30dogs100squirrels' | awk -v FPAT='[0-9]+|[^0-9]+' '{$1=$1}1'
50 cats 30 dogs 100 squirrels

1
你可以尝试这个:

echo 50cats30dogs100squirrels | awk '{while (match($0, /[0-9]+|[a-zA-Z]+/)) {print substr($0, RSTART, RLENGTH);$0=substr($0, RSTART+RLENGTH)}}'

这将产生:

50
cats
30
dogs
100
squirrels


1
使用gawk,这是gensub的工作,然后将其split成一个数组更容易:
gawk '
  BEGIN {
    s = "50cats30dogs100squirrels"
    t = gensub(/[[:alpha:]]+|[[:digit:]]+/, "& ", "g", s)
    print ">" t "<"
    split(t, a)
    for (i in a) print i, a[i]
  }
'

输出

>50 cats 30 dogs 100 squirrels <
1 50
2 cats
3 30
4 dogs
5 100
6 squirrels

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