【问题标题】:awk - match positive whole numbers and floating point numbers onlyawk - 仅匹配正整数和浮点数
【发布时间】:2016-09-21 13:55:11
【问题描述】:

我有一个 .csv 格式的输入文件,其中包含用管道分隔的税务发票条目。

例如:

Header--TIN | NAME | INV NO | DATE | NET | TAX | OTHERS | TOTAL
Record1-29001234768 | A S Spares | AB012 | 23/07/2016 | 5600.25 | 200.70 | 10.05 | 5811.00
Record2-29450956221 | HONDA Spare Parts | HOSS0987 |29/09/2016 | 70000 | 2200 | 0 | 72200

记录的 NET value、TAX Value、OTHER Charges 和 TOTAL value 列可能包含正整数或小数点后 2-4 位的正浮点数。

现在我的要求是通过检查适当的'Regular Expression using awk'来检查列是否满足指定的约束。 我需要用正则表达式匹配这 4 列,这样如果我遇到除正整数或正浮点数以外的任何数值,我需要向用户打印一条错误消息。

我尝试了以下方法,但它似乎不起作用。

if(!($5 ~ /[0-9]+/) || !($5 ~ /[0-9]+[.][0-9]+/) || ($5<=0))
    { printf("NET VALUE (Violates constraints)" }

谁能给出正确的工作正则表达式或使用内置函数的任何实现来满足我的要求?

【问题讨论】:

  • 不要忘记~ 运算符将返回真,如果正则表达式出现在被测试的字段中任何地方。例如:awk 'BEGIN { if ("abc8xyz" ~ /[0-9]+/) print "is this a hint?" }'
  • 您发布的输入文件中没有逗号,因此显然不是 CSV。 edit您的问题是向我们展示真正的 CSV 输入文件,或者如果那是您真正的输入格式,请删除有关 CSV 的讨论。
  • @Ed Morton - 为了更好地理解,我使用 sed 命令将所有逗号替换为管道。它当然是一个.csv文件,它是通过使用libreoffice转换一个.ods文件得到的,但是用管道替换了逗号。
  • 我理解这样做的诱惑,但不要这样做。如果您提供了我们可以测试的东西,那么我们将对其进行测试,如果您提供的东西不是您的真实输入,无论您认为它看起来多么漂亮或清晰,这都会使我们更难创建测试输入来自(所以我们大多数人都不会打扰)并且可能会导致您获得解决您实际上没有的问题的解决方案。

标签: bash awk


【解决方案1】:

听起来您的验证应该是:

$5 ~ /^[0-9]+(\.[0-9]{2,4})?$/

如果匹配,那么它是有效的(一个正整数,或者一个数字后跟 . 和 2 到 4 个其他数字)。

字段开始和结束的锚点很重要!

正如 cmets 中正确指出的那样,如果您想接受小数点前没有数字的数字,那么您将不得不使用更复杂的正则表达式。

【讨论】:

  • 哦..对不起...我在记录中的管道和值之间没有任何空格。
  • @Shreyas 请注意,我的模式中有一个错字(一个额外的括号),我已对其进行了编辑以删除。
  • @TomFenech:我试过这个echo "345.23" | awk '{ if($0 ~ /^[0-9]+(\.[0-9]{2,4})?$/) print "good" }',但它不起作用..它适用于没有小数点的数字
  • @Fazlin 你有一个史前版本的 gawk,所以在前面添加 --re-interval 以启用 RE 间隔,然后尽快获得更新版本的 gawk!
  • .10 是一个正浮点数,将被该正则表达式拒绝。
猜你喜欢
  • 2015-03-17
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 2015-07-18
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
  • 1970-01-01
相关资源
最近更新 更多