awk查询数字与字符串

时间:2015-11-05 20:40:21

标签: bash csv awk

我在R中编写一个函数,它将生成一个awk脚本,根据用户通过UI选择的条件从csv中提取行。

这是函数生成的字符串示例:

$ tail -n +2 ../data/faults_main_only_dp_1_shopFlag.csv |
>     parallel -k -q --block 500M --pipe \
>         awk -F , '$5 > "2013-01-01" && $5 < "2015-11-05" && ($3 == "20116688") && ($20 == "Disregard") {print  $1 "," $3 "," $17 "," $20 }' |
> head | csvlook

它不会返回任何内容,因为$3是一个数字变量。也没有:

$ tail -n +2 ../data/faults_main_only_dp_1_shopFlag.csv |
>     parallel -k -q --block 500M --pipe \
>         awk -F , '$5 > "2013-01-01" && $5 < "2015-11-05" && ($3 == 20116688) && ($20 == Disregard) {print  $1 "," $3 "," $17 "," $20 }' |
> head | csvlook

...因为$20是一个字符串。

这将返回数据集的一部分:

$ tail -n +2 ../data/faults_main_only_dp_1_shopFlag.csv |
>     parallel -k -q --block 500M --pipe \
>         awk -F , '$5 > "2013-01-01" && $5 < "2015-11-05" && ($3 == 20116688) && ($20 == "Disregard") {print $1 "," $3 "," $17 "," $20 }' |
> head | csvlook`

|---------+------------+------+------------|
|  5058.0 | 20116688.0 | 4162 | Disregard  |
|---------+------------+------+------------|
|  5060.0 | 20116688.0 | 3622 | Disregard  |
|  5060.0 | 20116688.0 | 3619 | Disregard  |
|  5061.0 | 20116688.0 | 766  | Disregard  |
|  5059.0 | 20116688.0 | 3603 | Disregard  |
|  5055.0 | 20116688.0 | 1013 | Disregard  |
|  5058.0 | 20116688.0 | 1012 | Disregard  |
|  5055.0 | 20116688.0 | 4163 | Disregard  |
|  5060.0 | 20116688.0 | 4225 | Disregard  |
|  5061.0 | 20116688.0 | 3466 | Disregard  |
|---------+------------+------+——————|

不幸的是,我目前没有办法预测用户通过UI选择哪些变量将是字符串或数字(我知道如何做到这一点,但我需要时间,而不是花钱,如果有一个解决方法)。有没有办法在比较之前将每个变量转换为字符串,或者有其他方法来处理这个问题?

编辑这就是原始数据的样子:

$ csvcut -c15:20 faults_main_only_dp_1_shopFlag.csv | head
faultActiveLongitude,faultActiveAltitude,faultCode,faultSoftwareVersion,stateID,stateName
-0.8100106,-1.0,3604,25.07.01 11367,2.0,Work Item
-0.81860137,840.0,766,25.07.01 11367,5.0,Disregard
-0.8100140690000001,-1.0,4279,25.07.01 11367,2.0,Work Item
-0.8100509640000001,-2.0,4279,25.07.01 11367,2.0,Work Item
-0.8102342,14.0,3604,25.07.01 11367,2.0,Work Item
-0.8181563620000001,831.0,3604,25.07.01 11367,5.0,Disregard
-0.81022054,11.0,3604,25.07.01 11367,2.0,Work Item
-0.8102272,11.0,4279,25.07.01 11367,2.0,Work Item
-0.8083836999999999,17.0,766,25.07.01 11367,5.0,Disregard

1 个答案:

答案 0 :(得分:0)

如果可以转换令牌,

awk可以进行int <-->字符串比较。请注意,您使用逗号作为字段分隔符,空格将成为字段的一部分。如果你的数字是整数不是小数点问题,

检查这三种情况

$ echo "42,42" | awk -F, '$1=="42" && $2==42{print "works";next} {print "does not work"}'
works

$ echo "42, 42" | awk -F, '$1=="42" && $2==42{print "works";next} {print "does not work"}'
works

$ echo "42 , 42" | awk -F, '$1=="42" && $2==42{print "works";next} {print "does not work"}'
does not work

字符串解释(第一个字段)不应该有空格!

您可以尝试将字段分隔符设置为" *, *"

更新:如果您的整数得到.0浮点扩展名,您可以忽略它们,请在比较前将它们转换为int

$ echo "42.0 , 42" | awk -v FS=" *, *" 'int($1)=="42" && $2=="42"{print "works";next} {print "does not work"}'
works

此处将引用您的通用值,但字段将在字符串转换之前转换为int。你需要知道哪些字段是数字的字段是字符串。