首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过regex匹配创建一个新列

通过regex匹配创建一个新列
EN

Unix & Linux用户
提问于 2022-06-05 23:21:55
回答 2查看 210关注 0票数 0

我将这些数据保存在一个. csv文件中:

代码语言:javascript
复制
age,sex,bmi,smoker,region,charges
19,female,23.9,yes,southwest,16884.924
23,male,29.83,no,northeast,1725.5523

我想创建一个新的专栏,基于参加第三栏(bmi)的一些模式。

代码语言:javascript
复制
desnutrition='^([^,]*,){3}[1][0-7].[0-9]*'
low='^([^,]*,){3}[1][8-9].[0-9]*'
normal='^([^,]*,){3}[2][0-4].[0-9]*'
high='^([^,]*,){3}[2][5-9].[0-9]*'
obesity='^([^,]*,){3}[3-4][0-9].*'

期望的输出是:

代码语言:javascript
复制
age,sex,bmi,smoker,region,charges,bmi_level
19,female,23.9,yes,southwest,16884.924,normal
23,male,29.83,no,northeast,1725.5523,high

有没有办法做到这一点(最好是使用bash或awk)?

EN

回答 2

Unix & Linux用户

发布于 2022-06-06 01:20:47

如果我正确地理解了您的regexp,我想这就是您要做的:

代码语言:javascript
复制
$ cat tst.awk
BEGIN { FS=OFS="," }
NR == 1 {
    level = "bmi_level"
}
NR > 1 {
    bmi = $3
    if      ( bmi >= 30 ) { level = "obese" }
    else if ( bmi >= 25 ) { level = "high" }
    else if ( bmi >= 20 ) { level = "normal" }
    else if ( bmi >= 18 ) { level = "low" }
    else                  { level = "desnutrition" }
}
{ print $0, level }
代码语言:javascript
复制
$ awk -f tst.awk file
age,sex,bmi,smoker,region,charges,bmi_level
19,female,23.9,yes,southwest,16884.924,normal
23,male,29.83,no,northeast,1725.5523,high

如果这是不完全正确的,希望这是显而易见的,如何调整数字。

票数 2
EN

Unix & Linux用户

发布于 2022-06-07 09:33:51

regex似乎错了

  • ^([^,]*,){3}指的是前三个字段,您只需要前两个字段。

我不确定^([^,]*,){2}也会做你想做的事。

使用您的数据,以及正常的行

  • sed -n -e '/^([^,]*,){2}[2][0-4].[0-9]*/p' data.csv无结果
  • sed -n -e '/^[^,]*,[^,]*,[2][0-4].[0-9]*/p' data.csv找到合适的线。

我重写了你的regex

代码语言:javascript
复制
desnutrition=^[^,]*,[^,]*,[1][0-7].[0-9]*
low=^[^,]*,[^,]*,[1][8-9].[0-9]*
normal=^[^,]*,[^,]*,[2][0-4].[0-9]*
high=^[^,]*,[^,]*,[2][5-9].[0-9]*
obesity=^[^,]*,[^,]*,[3-4][0-9].*

您可以使用awk在sed脚本中调用thoses regex。

代码语言:javascript
复制
awk -F= '{ printf "/%s/s/^.*$/&,%s/\n",$2,$1 ;}' range2.lst
/^[^,]*,[^,]*,[1][0-7].[0-9]*/s/^.*$/&,desnutrition/
/^[^,]*,[^,]*,[1][8-9].[0-9]*/s/^.*$/&,low/
/^[^,]*,[^,]*,[2][0-4].[0-9]*/s/^.*$/&,normal/
/^[^,]*,[^,]*,[2][5-9].[0-9]*/s/^.*$/&,high/
/^[^,]*,[^,]*,[3-4][0-9].*/s/^.*$/&,obesity/

然后将sed脚本提供给sed

代码语言:javascript
复制
awk -F= '{ printf "/%s/s/^.*$/&,%s/\n",$2,$1 ;}' range2.lst | sed -f - data.csv
age,sex,bmi,smoker,region,charges
19,female,23.9,yes,southwest,16884.924,normal
23,male,29.83,no,northeast,1725.5523,high

我没有给出详细的awk或生成的sed命令,因为,除非这样做是为了好玩或教程,我会再次推荐Ed更直截了当的答案

票数 0
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/705092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档