使用 sed 将货币格式更改为通用数字

使用 sed 将货币格式更改为通用数字

我正在处理一个大型 csv 文件,其中包含所有逗号分隔的条目。整个文档由纯数字组成,除了几列反映格式化为文本的货币之外。例如,一个这样的条目可能看起来相似"$12,345.67",而另一个条目也可能相似"$1,234,567.89" (双引号符号也包含在条目中)。以下是完整数据记录(一行)的示例:

123,7,11,"$343,700.14","$34,928.63","$377,000.00","$15,421.92",19,2

我想对此数据文件进行一些处理,因此,我想将此类文本字段重新格式化为纯数字(即摆脱双引号和逗号)。我认为正则表达式模式替换sed应该适合我,但我根本不确定正则表达式是什么样的。任何想法将不胜感激。

答案1

表达应该做什么很简单:

"$1 对于和之间包含的每个字符串,"删除所有,
2 删除周围的"$"

这是 sed 表达式。如果您在命令行上使用它,则必须适当地引用它。将它放在一个文件中更简单,例如command.sed,然后通过以下方式调用它

sed -f command.sed data.csv

这是实现这两个步骤的程序:

:repeat
s/"\$\([^,"]*\),/"$\1/g 
t repeat
s/"\$\([^"]*\)"/\1/g 

文档帮助我解决了问题。

答案2

更新:调整答案仅替换引号之间的空格来处理这个问题。

命令:

echo '123,7,11,"$343,700.14","$34,928.63","$377,000.00","$15,421.92",19,2' |
awk -F\" '{OFS="\""; for (i = 2; i < NF; i += 2) gsub(/[$,]/,"",$i); gsub(/"/,""); print}'

输出:

123,7,11,343700.14,34928.63,377000.00,15421.92,19,2

第一个gsub删除双引号内的$s 和s。,第二个删除引号本身。

在下面留下原始答案以防有帮助。

如果我理解正确的话,简单的搜索和替换就可以了

echo '"$1,234,567.89"' | sed 's/[$,"]//g'

输出1234567.89

其作用是替换与 ( ) 匹配的 ( )s字符,并且不替换任何内容(最后两个 之间为空。该标志使其全局适用,替换所有实例(否则仅替换行中的第一个实例)。[]$,"/g

如何将其应用于整个文件取决于文件的格式。如果文件中没有其他内容包含双引号、美元符号和逗号,则应该很好:

sed 's/[$,"]//g' /path/to/file

答案3

此货币值的显示方式取决于您的 CSV 查看器,为什么您不更改 Excel 中的“视图”而不是更改此字段?

不管怎样,您的 csv 字段中可能有多个字段,因此使用如下处理程序脚本会更安全:

#!/usr/bin/perl

use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new ( { binary => 1 } );
while ( my $row = $csv->getline(\*STDIN) ) {
    foreach my $item (@$row)
    {
        $item =~ s/,//g if ($item =~ /^\$[0-9,.]+$/);
    }
    $csv->print (\*STDOUT, $row);
    print "\n";
}

用法:./csv.pl < in.csv > ou.csv

输入:

abc,"$1,243,311.99",def
abc2,"$43,311.99",def2

输出:

abc,$1243311.99,def
abc2,$43311.99,def2

答案4

一个稍微复杂的 awk 解决方案,基于使用 awk 解析 CSV

{
$0=$0",";                                  # yes, cheating
while($0) {
  gsub(/\$/,"",$0)
  match($0,/ *"[^"]*" *,|[^,]*,/);
  sf=f=substr($0,RSTART,RLENGTH);          # save what matched in sf
  gsub(/^ *"?|"? *,$/,"",f);               # remove extra stuff
  gsub(/,/,"",f);
  if($0 ~ /,[^,]+,$/){
    printf "%s,",f;
  }else{
    printf "%s",f;
  }
  sub(sf,"");                              # "consume" what matched
}
printf "\n"
}

将上面的内容保存为 csv.awk 并像这样运行:

echo '123,7,11,"$343,700.14","$34,928.63","$377,000.00","$15,421.92",19,2'|awk -f csv.awk
123,7,11,343700.14,34928.63,377000.00,15421.92,19,2

相关内容