我想取出一定范围的巨大数值,即720000002774991000到720000002774991099。所以我尝试了以下命令,
awk -F, ' { if (($1 >= 720000002774991000) && ($1 <= 720000002774991099)) print $0} ' VOUCHER_DUMP_REPORT.csv | head
VOUCHER_DUMP_REPORT.csv是我的输入文件,并且只有一列如此庞大的数字。
但是我得到的输出不准确,除了我给定的范围外,它还有一些其他值。
输出:
720000002774991065
720000002774991082
720000002774990985
720000002774991131
720000002774990919
720000002774991110
720000002774990947
720000002774991070
720000002774991042
720000002774991044
答案 0 :(得分:2)
看起来您的数字太长,无法正确表示为整数。
您有两种可能的解决方案。使用GNU awk,您可以使用-M
启用对arbitrary precision integers的支持:
awk -M '$1 >= 720000002774991000 && $1 <= 720000002774991099' file
否则,如果您确定第一列仅包含数字,则可以使用字符串比较:
awk -F, -v min=720000002774991000 -v max=720000002774991099 '
BEGIN { lmin = length(min); lmax = length(max) } # save length of min and max
"" $1 < min || "" $1 > max { next } # skip lines which fail string comparison
{ l1 = length($1) } # calculate length of field
l1 >= lmin && l1 <= lmax # check that string length is correct
' file
"" $1
将空字符串与第一个字段的内容连接在一起,这迫使awk将其视为字符串而不是数字。没有这个,比较将是数字的,而不是词汇的,并且您将遇到与原始尝试相同的问题。
使用字符串比较的效率可能较低但较易理解的版本是:
awk -F, -v min=720000002774991000 -v max=720000002774991099 '
"" $1 >= min && "" $1 <= max \
&& length($1) >= length(min) && length($1) <= length(max)' file
与以前的版本一样,打印的行同时通过字符串比较和长度比较。这种方法的缺点是min
,max
和$1
的长度计算得比必要的次数更多。
$ cat file
720000002774991065
720000002774991082
720000002774990985
720000002774991131
720000002774990919
720000002774991110
720000002774990947
720000002774991070
720000002774991042
720000002774991044
$ awk -M '$1 >= 720000002774991000 && $1 <= 720000002774991099' file
720000002774991065
720000002774991082
720000002774991070
720000002774991042
720000002774991044
$ awk -F, -v min=720000002774991000 -v max=720000002774991099 '
BEGIN { lmin = length(min); lmax = length(max) } # save length of min and max
"" $1 < min || "" $1 > max { next } # skip lines which fail string comparison
{ l1 = length($1) } # calculate length of field
l1 >= lmin && l1 <= lmax # check that string length is correct
' file
720000002774991065
720000002774991082
720000002774991070
720000002774991042
720000002774991044
$ awk -F, -v min=720000002774991000 -v max=720000002774991099 '
"" $1 >= min && "" $1 <= max \
&& length($1) >= length(min) && length($1) <= length(max)' file
720000002774991065
720000002774991082
720000002774991070
720000002774991042
720000002774991044