정규식 일치로 새 열 만들기

정규식 일치로 새 열 만들기

. 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

재미나 튜토리얼을 위해 이 작업을 수행하지 않는 한 Ed Morton의 보다 간단한 답변을 권장하기 때문에 의도적으로 세부 정보나 awk생성된 명령을 제공하지 않을 것입니다.sed

관련 정보