shell regex:提取价格

鉴于以下价格清单,我试图弄清楚如何标准化/仅提取数字.

INPUT          DESIRED_OUTPUT

CA$1399.00     1399.00
$1399.11   1399.11
$1,399.22<     1399.22
Z$1 399.33     1399.33
$1399.44#      1399.44
C$1399.55     1399.55
1,399.66       1399.66
1399.77        1399.77
,1399.88       1399.88
25 1399.88     1399.88
399.99          399.99
88.88 99.99      99.99 (if >2 matches on one line, only the last one matters)
.1399.88         DO NOT MATCH (not a price; too many ".")
666.000          DO NOT MATCH (not a price: too many 0's)

我想开始的是他们都有共同点的好主意:

>价格始终包含.NN,但从不包含.NNN

经过进一步检查,其他规则变得明显:

> .NN必须以一个或多个数字开头.
> NNN.NN前面可以是,,或简单的数字,但没有别的.
>任何跟随.NN和前面的* N.NN标记比赛结束.
>最后,正则表达式需要考虑像1,399.66(1399.66)之类的逗号,以确定它是否是一个价格,然后剥离它们.例如,1,399.66不等于1399.66:它应该是399.66.

我正在寻找sed,grep和awk以获得便携而有效的解决方案.我该如何处理这个问题呢?

我找到了similar question,但我不知道如何使用sed尝试以下正则表达式:

^\d+(,\d{1,2})?$

编辑:是的,我的输入格式可能有点奇怪,因为它是拼接页面串联的结果.

最佳答案 您可以使用以下shell脚本:

#/bin/sh
grep -v '\.\d\+\.' | # get rid of lines with multiple dots within the same number
grep -v '\.\d\d\d\+' | # get rid of lines with more than 2 digits after .
sed -e 's/\(.*\.[0-9][0-9]\).*$/\1/' | # remove anything after last .NN
sed -e 's/^.* \([0-9][0-9][0-9][0-9]\)\./\1./' | # "* NNNN." => "NNNN."
sed -e 's/^.* \([0-9][0-9]\)\./\1./' | # "* NN." => "NN."
sed -e 's/^.* \([0-9]\)\./\1./' | # "* N." => "N."
sed -e 's/^\(.*\)[ ,]\(\([0-9]\)\{3,\}\)\./\1\2./g' | # "*,NNN." or "* NNN." => "*NNN."
sed -e 's/^\(.*\)[ ,]\(\([0-9]\)\{6,\}\)\./\1\2./g' | # "*,NNNNNN." or "* NNNNNN." => "*NNNNNN."
sed -e 's/^\(.*\)[ ,]\(\([0-9]\)\{9,\}\)\./\1\2./g' | # "*,NNNNNNNNN." or "* NNNNNNNNN." => "*NNNNNNNNN."
grep -o '\d\+\.\d\d' # print only the price

如果数字由空格分隔,或者以3位数字组合,此解决方案最多可以在9位之前运行.如果您需要提取更大的价格,只需添加更多行,将正则表达式中的数字增加3. 😉

将它放在一个名为extract_prices的文件中,使其可执行(chmod x extract_prices)并运行它:./extract_prices< my_list.txt 使用以下输入在OS X上测试:

CA$1399.00
&#36;1399.11
$1,399.22<
Z$1 399.33
Z$12 777 666.34   # <-- additonal monster price
$1399.44#
C$1399.55
1,399.66
1399.77
,1399.88
25 1399.88
399.99
88.88 99.99
.1399.88
666.000

这会生成以下输出:

1399.00
1399.11
1399.22
1399.33
12777666.34
1399.44
1399.55
1399.66
1399.77
1399.88
1399.88
399.99
99.99
点赞