2015-05-06 189 views
0

我有一個條目,如大文件:刪除逗號和格式的日期

<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領域的逗號和更改日期YYYY-MM-DD(例如,2013年7月-31)在DATE字段中。

尋找快速(高效)的方法。

感謝

+0

'用VALUE字段替換逗號? – Jotne

+0

對不起,刪除,而不是替換 – tozjerimiah

+0

看看strtotime()和替換() – Matheno

回答

1
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有沒有額外的子外殼爲DAE轉換sed的
  • 格式化日起2 s///在這裏,但可能會在1 s///更unreadeable位(已經非常有吸引力的正則表達式是這樣)合併
  • 可以很容易地添加一些關於源日期的安全功能,如錯誤的日期格式
+0

這已經真的對我有用,我學到了很多東西,謝謝 – tozjerimiah

2

這應該讓你開始:

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> 
+0

輝煌 - 我找到了這個:http://stackoverflow.com/questions/14342108/converting-months-between-numeric-and- number-using-awk - 您能否展示如何將解決方案與您的解決方案集成在一起,以便只需要通過一次文件傳遞? – tozjerimiah

+0

感謝您的編輯 - 我得到了'awk:fatal:不匹配(或\(:/ {split($ 3,a,「」); $ 0 = sprintf(「%s-%02d-%s tozjerimiah

+0

@tozjerimiah複製過去的錯誤,並且在月和日中添加了'%0d'來獲取正確的數字 – Jotne

1

你輸入好像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 ; 
+0

尋找速度,因爲它是一個很長的文件 - 謝謝你 – tozjerimiah

1

這可能會爲你工作(GNU sed的&的bash):

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

這消除了對開始<VAL>線,併爲那些包含日期行所有的逗號標記,使用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線的末端,並使用正則表達式來重新排列輸出。

+0

感謝你的幫助 – tozjerimiah