通过正则表达式匹配创建新列

通过正则表达式匹配创建新列

我在一个. csv文件中有这些数据:

age,sex,bmi,smoker,region,charges
19,female,23.9,yes,southwest,16884.924
23,male,29.83,no,northeast,1725.5523

我想根据第三列(bmi)的一些模式创建一个新列。

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].*'

期望的输出是:

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)?

答案1

如果我正确理解你的正则表达式,我认为这就是你想要做的:

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

$ 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

正则表达式似乎错误

  • ^([^,]*,){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找到合适的线。

所以我重写了你的正则表达式

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 脚本

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

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 Morton)更直接的答案

相关内容