我正在使用一个有点自由格式的 csv 文件,需要有效地查找费用条目。我更好的解决方案是测试每一行中特定列的数量。我尝试了以下方法(GNU bash,版本 5.0.17),但它不起作用(没有返回“是美元金额”):
#!/bin/bash
input=$1
if [[ $input == [\$]?[0-9][\,]?[0-9]*[\.]?[0-9]{2}?$ ]]
then
echo "Is a dollar amount"
else
echo "Is NOT a dollar amount"
fi
我尝试过美元符号、逗号和句点刚刚转义(没有括号),但这也不起作用。我单引号包含美元符号的参数(必须)。我将 == 更改为 =~ 并且太多可能性报告“是美元金额”。在网络上搜索类似的东西几乎是不可能的。我究竟做错了什么?我以为我写的意思是:
- 前导美元符号是可选的 - [$]?
- 至少需要一位数字 - [0-9]
- 逗号是可选的 - [,]?
- 任何数量的附加数字都是可接受的 - [0-9]*
- 句点是可选的 - [.]?
- 可以有两个附加数字,但这也是可选的 - [0-9]{2}?
- 最后两位数字后没有任何内容 - $
答案1
您可能想使用=~
运算符而不是==
进行测试,并且不能使用?
after {2}
。
说“没有或两位数字”的正确方法是([0-9]{2})?
。
你最终得到的是
if [[ $input =~ ^\$?[0-9],?[0-9]*\.?([0-9]{2})?$ ]]; then ...; fi
在这里,我还将表达式锚定到行的开头,^
并删除了一些不必要的方括号。
如果字符串中可选的部分不是独立可选的,您可能需要将这些部分放在括号中,例如,
if [[ $input =~ ^\$?[0-9](,[0-9]+)?(\.[0-9]{2})?$ ]]; then ...; fi
如果有逗号,则要求逗号后至少有一位数字;如果是点,则要求点后至少有两位数字。
答案2
感谢@they 的上述帖子让我找到了答案:
if [[ $input =~ ^\$?[0-9]{1,3}(,[0-9]{3})*(\.[0-9]{2})?$ ]]
我发现我犯了很多错误。我将上面的脚本称为“测试”并尝试了几种变体(见下文),它们都按预期响应。
以下报道“是美元金额”
- ./测试1
- ./测试75
- ./测试453
- ./测试'$453'
- ./测试1,234
- ./测试1,234.89
- ./测试1,234,657.89
以下报道“不是美元金额”
- ./测试1a234,657.89
- ./test 1,234.657.89(注意两个句点)
- ./test 1,234,657.9(缺少美分数字)