awk 在分隔符中读取像逗号一样的分号并断开一些行

问题描述 投票:0回答:1

CSV 示例

date,string,number
10/11/2012,Psychology; enroute to (15 n freeway),12.3

我正在创建一个接收 CSV 的 awk 脚本,当它读取时,如果在数字列中找到浮点数,它会在另一个 csv 中记录行。

使用示例 csv,我的程序无法正确读取该行,因为它正在分割 ;分为 2 个字段。然后当我检查 $3 时,它无法读取浮点数,因为 $3 = 前往(15 n 高速公路)的途中

田野

$1 = 10/11/2012
$2 = Psychology
$3 =  enroute to (15 n freeway)
$4 = 12.3

所需字段

$1 = 10/11/2012
$2 = Psychology; enroute to (15 n freeway)
$3 = 12.3

我原来的FS是:

FS = ","
OFS = ","

我尝试将其放入 FS 但不起作用。

FS = ",|;[[:space:]]*"

编辑:我尝试这个,因为chatgpt这么说,但我不知道如何解决这个问题。

我的代码

    #!/usr/bin/awk -f

function write_line(line, filename) {
    print line > filename
}


function check_float(duration) {
    return number ~ /[0-9]*(\.[0-9]+)/
}


BEGIN {
    FS = ","
    OFS = ","

    float_numbers = "float_numbers.csv"

}

{
    if ( NR == 1 ) {
       header = "date,string,number"
       print header > float_numbers
    }
    else {
        if (!check_float($3)) {
            write_line($0, float_numbers)
        }

    }

}

END {
    close(float_numbers)
}

你能帮我吗?

谢谢你。

awk
1个回答
0
投票

第一期:

第二个函数是使用名为

duration
(
check_float(duration)
) 的(本地)输入参数定义的,但在函数体内您要比较(全局)变量
number
。由于您从未定义/填充名为
number
的全局变量,因此比较 (
number ~ /[0-9]*(\.[0-9]+)/
) 始终返回 0。我假设您真正想要做的是比较(本地)输入参数
duration
,即:

return duration ~ /[0-9]*(\.[0-9]+)/

第二期:

看来

check_float()
函数的目的是,如果
1
是浮点数,则返回
duration
,否则返回
0
。但是,当在脚本主体中调用该函数时,结果会被否定 -
!check_float($3)
。从文字描述中您提到将带有浮点数的行打印到单独的文件中。最终结果:我假设您不想想要否定
check_float()
调用的结果。

第三期:

对于像

1
这样的值,浮点比较将匹配(因此返回
1.2.3.4
)。您需要考虑做的是锚定字段的开始 (
^
) 和结束 (
$
)。假设没有前导/尾随空格,以下内容应该足够了:

/^[0-9]*(\.[0-9]+)$/`

添加一些示例数据来验证我们对

check_float()
函数的更改:

$ date,string,number
10/11/2012,Psychology; enroute to (15 n freeway),12.3
10/12/2013,Psychology; enroute to (15 n freeway),12
10/13/2014,Psychology; enroute to (15 n freeway),twelve point 3
10/14/2015,Psychology; enroute to (15 n freeway),1.2.3.4
10/14/2015,Psychology; enroute to (15 n freeway),help.me.please

更新 OP 的当前代码并修复三个问题:

$ cat sample.awk

#!/usr/bin/awk -f

function write_line(line, filename) {
    print line > filename
}

function check_float(duration) {
    return duration ~ /^[0-9]*(\.[0-9]+)$/
#          ^^^^^^^^    ^                ^
}

BEGIN { FS = ","
        OFS = ","
       float_numbers = "float_numbers.csv"
}

{ if ( NR == 1 ) {
     header = "date,string,number"
     print header > float_numbers
  }
  else {
     if (check_float($3)) {
#        ^^^^^^^^^^^^^^^ do not negate with !
        write_line($0, float_numbers)
     }
  }
}

END { close(float_numbers) }

试驾:

$ awk -f sample.awk sample.csv

$ cat float_numbers.csv
date,string,number
10/11/2012,Psychology; enroute to (15 n freeway),12.3
© www.soinside.com 2019 - 2024. All rights reserved.