【问题标题】:Remove commas and format dates删除逗号和格式化日期
【发布时间】:2015-07-16 12:05:51
【问题描述】:

我有一个大文件,其中包含以下条目:

<VAL>17,451.26</VAL>
<VAL>353.93</VAL>
<VAL>395.00</VAL>
<VAL>2,405.00</VAL>
<DATE>31 Jul 2013</DATE>
<DATE>31 Jul 2013</DATE>
<DATE>31 Dec 2014</DATE>
<DATE>21 Jun 2002</DATE>
<DATE>10 Jul 2002</DATE>
<MOD>PL</MOD>
<BATCH>13382</BATCH>
<TYPE>Invoice</TYPE>
<REF1>13541/13382</REF1>
<REF2>671042638320</REF2>
<NOTES>a-07 final elec</NOTES>
<SNAME>EDF ENERGY ( Electricity )</SNAME>
<VAL>55.22</VAL>
</CLT>
<CLT>
<CHD>MAT-01</CHD>
<OPN>U5U1</OPN>
<PERIOD>07 2013</PERIOD>
<DATE>13 Jun 2013</DATE>
<DATE>10 Jul 2002</DATE>
<DATE>10 Jul 2002</DATE>
<DATE>21 Aug 2007</DATE>
<DATE>10 Jul 2002</DATE>
<VAL>-4,122,322.03</VAL>

我需要删除 VAL 字段中的逗号,并将 DATE 字段中的日期更改为 YYYY-MM-DD(例如 2013-07-31)。

寻找一种快速(有效)的方法。

谢谢

【问题讨论】:

  • Replace the commas in the VAL fields 用什么?
  • 抱歉,删除,不是替换
  • 看看strtotime()和replace()

标签: awk sed grep tr nawk


【解决方案1】:

这应该让你开始:

awk -F"[<>]" 'BEGIN {split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec",month," ");for (i=1;i<=12;i++) mdigit[month[i]]=i} /<VAL>/ {gsub(/\,/,"")} /<DATE>/  {split($3,a," ");$0=sprintf("<DATE>%s-%02d-%02d</DATE>",a[3],mdigit[a[2]],a[1])}1' file
<VAL>17451.26</VAL>
<VAL>353.93</VAL>
<VAL>395.00</VAL>
<VAL>2405.00</VAL>
<DATE>2013-07-31</DATE>
<DATE>2013-07-31</DATE>
<DATE>2014-12-31</DATE>
<DATE>2002-06-21</DATE>
<DATE>2002-07-10</DATE>
<MOD>PL</MOD>
<BATCH>13382</BATCH>
<TYPE>Invoice</TYPE>
<REF1>13541/13382</REF1>
<REF2>671042638320</REF2>
<NOTES>a-07 final elec</NOTES>
<SNAME>EDF ENERGY ( Electricity )</SNAME>
<VAL>55.22</VAL>
</CLT>
<CLT>
<CHD>MAT-01</CHD>
<OPN>U5U1</OPN>
<PERIOD>07 2013</PERIOD>
<DATE>2013-06-13</DATE>
<DATE>2002-07-10</DATE>
<DATE>2002-07-10</DATE>
<DATE>2007-08-21</DATE>
<DATE>2002-07-10</DATE>
<VAL>-4122322.03</VAL>

【讨论】:

  • 太棒了 - 我发现了这个:stackoverflow.com/questions/14342108/… - 你能说明如何将解决方案与你的解决方案集成在一起,这样文件只需要通过一次吗?
  • 感谢您的编辑 - 我收到了 awk: fatal: Unmatched ( or \(: / {split($3,a," ");$0=sprintf("&lt;DATE&gt;%s-%02d-%s&lt;/ 不过 @Jotne
  • @tozjerimiah 复制过去的错误。还添加了%0d 以获得正确的月份和日期数字。
【解决方案2】:

您的输入看起来像 XML。我会使用适当的 XML 处理工具,例如XML::XSH2,Perl 的 XML::LibXML 的包装器:

open file.xml ;
for //VAL set . xsh:subst(., ',', '','g') ;
perl { use Time::Piece } ;
for my $d in //DATE {
    $t = $d/text() ;
    set $d/text() { Time::Piece->strptime($t, '%d %b %Y')->ymd } ;
}
save :b ;

【讨论】:

    【解决方案3】:

    这可能对你有用(GNU sed 和 bash):

    sed  -r '/^<VAL>/s/,//g;/^(<DATE>)(.*)(<\/DATE>)$/s//echo "\1"$(date -d "\2" +%F)"\3"/e' file
    

    这将删除以&lt;VAL&gt; 开头的行上的所有逗号,对于那些包含日期标签的行,使用date 实用程序和替换命令中的评估标志将日期重新排列为YYYY-MM-DD

    另一种解决方案,仅使用 seds 命令:

    sed  -r '/^<VAL>/s/,//g;/^<DATE>/!b;s/$/\nJan01Feb02Mar03Apr04May05Jun06Jul07Aug08Sep09Oct10Nov11Dec12/;s/^(<DATE>)(..) (...) (....)(<\/DATE>\n).*\3(..)/\1\4-\6-\2\5/;P;d' file
    

    将查找追加到date 行的末尾并使用正则表达式重新排列输出。

    【讨论】:

      【解决方案4】:
      sed '# init month convertor in holding buffer
      1{h;s/.*/Jan01Fev02Mar03Apr04May05Jun06Jul07Aug08Sep09Oct10Nov11Dec12/;x;}
      
      # change Val
        /^<VAL>/ s/,//g
      
      # Change Date
        /^<DATE>/ {
      # change month
          G
          s/[[:space:]]\{1,\}\([A-Z][a-z][a-z]\)[[:space:]]\{1,\}\(.*\)\n.*\1\([0-9][0-9]\).*/-\3-\2/
      # reformat order
          s/>\(.*\)-\(.*\)-\(.*\)</>\3-\2-\1</
        }' YourFile
      
      • posix sed 没有用于 dae 转换的额外子 shell
      • reformat date take 2 s///here 但可以合并到 1 s/// 有点不可读(像这样已经非常有吸引力的正则表达式)
      • 可以轻松添加一些关于源日期的安全功能,例如错误的日期格式

      【讨论】:

      • 这对我来说真的很有用,我学到了很多东西。谢谢
      猜你喜欢
      • 2013-01-29
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 2017-05-24
      • 2015-09-13
      相关资源
      最近更新 更多