使用 AWK 从大量数字列表中获取特定范围的数值
Fetching a specific range of numeric value from huge list of numbers using AWK
我想取出特定范围的巨大数值,720000002774991000 到 720000002774991099。所以我尝试了以下命令,
awk -F, ' { if (( >= 720000002774991000) && ( <= 720000002774991099)) print [=10=]} ' VOUCHER_DUMP_REPORT.csv | head
VOUCHER_DUMP_REPORT.csv 是我的输入文件,只有一列这么大的数字。
但是我得到的输出不准确,它有一些不同于我给出的范围的值。
输出:
720000002774991065
720000002774991082
720000002774990985
720000002774991131
720000002774990919
720000002774991110
720000002774990947
720000002774991070
720000002774991042
720000002774991044
您的数字似乎太长,无法正确表示为整数。
您有几个可能的解决方案。使用 GNU awk,您可以使用 -M
启用对 arbitrary precision integers:
的支持
awk -M ' >= 720000002774991000 && <= 720000002774991099' file
否则,如果您确定第一列仅包含数字,则可以使用字符串比较:
awk -F, -v min=720000002774991000 -v max=720000002774991099 '
BEGIN { lmin = length(min); lmax = length(max) } # save length of min and max
"" < min || "" > max { next } # skip lines which fail string comparison
{ l1 = length() } # calculate length of field
l1 >= lmin && l1 <= lmax # check that string length is correct
' file
""
将空字符串与第一个字段的内容连接起来,这会强制 awk 将其视为字符串而不是数字。如果没有这个,比较将是数字的,而不是词汇的,并且您将遇到与最初尝试相同的问题。
一个可能效率较低但可能更容易理解的使用字符串比较的版本是:
awk -F, -v min=720000002774991000 -v max=720000002774991099 '
"" >= min && "" <= max \
&& length() >= length(min) && length() <= length(max)' file
和之前的版本一样,打印通过字符串比较和长度比较的行。这种方法的缺点是 min
、max
和 </code> 的长度计算次数超过了必要的次数。</p>
<hr>
<h3>测试(以上三种方法)</h3>
<pre><code>$ cat file
720000002774991065
720000002774991082
720000002774990985
720000002774991131
720000002774990919
720000002774991110
720000002774990947
720000002774991070
720000002774991042
720000002774991044
$ awk -M ' >= 720000002774991000 && <= 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
"" < min || "" > max { next } # skip lines which fail string comparison
{ l1 = length() } # 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 '
"" >= min && "" <= max \
&& length() >= length(min) && length() <= length(max)' file
720000002774991065
720000002774991082
720000002774991070
720000002774991042
720000002774991044
我想取出特定范围的巨大数值,720000002774991000 到 720000002774991099。所以我尝试了以下命令,
awk -F, ' { if (( >= 720000002774991000) && ( <= 720000002774991099)) print [=10=]} ' VOUCHER_DUMP_REPORT.csv | head
VOUCHER_DUMP_REPORT.csv 是我的输入文件,只有一列这么大的数字。
但是我得到的输出不准确,它有一些不同于我给出的范围的值。
输出:
720000002774991065
720000002774991082
720000002774990985
720000002774991131
720000002774990919
720000002774991110
720000002774990947
720000002774991070
720000002774991042
720000002774991044
您的数字似乎太长,无法正确表示为整数。
您有几个可能的解决方案。使用 GNU awk,您可以使用 -M
启用对 arbitrary precision integers:
awk -M ' >= 720000002774991000 && <= 720000002774991099' file
否则,如果您确定第一列仅包含数字,则可以使用字符串比较:
awk -F, -v min=720000002774991000 -v max=720000002774991099 '
BEGIN { lmin = length(min); lmax = length(max) } # save length of min and max
"" < min || "" > max { next } # skip lines which fail string comparison
{ l1 = length() } # calculate length of field
l1 >= lmin && l1 <= lmax # check that string length is correct
' file
""
将空字符串与第一个字段的内容连接起来,这会强制 awk 将其视为字符串而不是数字。如果没有这个,比较将是数字的,而不是词汇的,并且您将遇到与最初尝试相同的问题。
一个可能效率较低但可能更容易理解的使用字符串比较的版本是:
awk -F, -v min=720000002774991000 -v max=720000002774991099 '
"" >= min && "" <= max \
&& length() >= length(min) && length() <= length(max)' file
和之前的版本一样,打印通过字符串比较和长度比较的行。这种方法的缺点是 min
、max
和 </code> 的长度计算次数超过了必要的次数。</p>
<hr>
<h3>测试(以上三种方法)</h3>
<pre><code>$ cat file
720000002774991065
720000002774991082
720000002774990985
720000002774991131
720000002774990919
720000002774991110
720000002774990947
720000002774991070
720000002774991042
720000002774991044
$ awk -M ' >= 720000002774991000 && <= 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
"" < min || "" > max { next } # skip lines which fail string comparison
{ l1 = length() } # 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 '
"" >= min && "" <= max \
&& length() >= length(min) && length() <= length(max)' file
720000002774991065
720000002774991082
720000002774991070
720000002774991042
720000002774991044