Shell-Script
根據日期和月份排列程式碼塊部分
我有一個像這樣重複內容的文件;
<item> <date>August 24, 2021</date> <p>Text</p> </item> <item> <date>February 11, 2020</date> <p>more text</p> </item> <item> <date>July 20, 2021</date> <p>some text</p> </item>
我希望得到一些東西,其中整個項目部分將按日期排列,其中第一個部分項目是最新日期,最後一個部分項目是最舊日期,像這樣;
<item> <date>August 24, 2021</date> <p>Text</p> </item> <item> <date>July 20, 2021</date> <p>some text</p> </item> <item> <date>February 11, 2020</date> <p>more text</p> </item>
有沒有可能用 sed 或 awk 來做這件事?
希望有人會為您提供使用 XML 感知工具的答案,但如果不是,並且假設您的輸入確實看起來像您提供的範例 - 使用 GNU awk
sorted_in
:$ cat tst.awk BEGIN { RS=""; ORS="\n\n"; FS="</?date>" } { split($2,d,/[, ]+/) mthAbbr = substr(d[1],1,3) mthNr = ( index( "JanFebMarAprMayJunJulAugSepOcNovDec", mthAbbr ) + 2 ) / 3 date = sprintf("%04d%02d%02d",d[3], mthNr, d[2]) items[date] = $0 } END { PROCINFO["sorted_in"] = "@ind_num_desc" for ( date in items ) { print items[date] } }
$ awk -f tst.awk file <item> <date>August 24, 2021</date> <p>Text</p> </item> <item> <date>July 20, 2021</date> <p>some text</p> </item> <item> <date>February 11, 2020</date> <p>more text</p> </item>
或使用任何 awk 加排序和剪切:
$ cat tst.awk BEGIN { RS=""; FS="\n"; OFS="\t" } { split($2,d,/[<>, ]+/) mthAbbr = substr(d[3],1,3) mthNr = ( index( "JanFebMarAprMayJunJulAugSepOcNovDec", mthAbbr ) + 2 ) / 3 date = sprintf("%04d%02d%02d",d[5], mthNr, d[4]) for (i=1; i<=NF; i++) { print date, NR, i, $i } print date, NR, i, "" }
$ awk -f tst.awk file | sort -k1,1rn -k2,3n | cut -f4- <item> <date>August 24, 2021</date> <p>Text</p> </item> <item> <date>July 20, 2021</date> <p>some text</p> </item> <item> <date>February 11, 2020</date> <p>more text</p> </item>
如果您的輸入文件很大,第二個將是更好的選擇,因為它不需要 awk 在列印之前將整個輸入文件保存在記憶體中。它的工作原理是裝飾輸入行,為每個添加日期,
item
後跟目前記錄 (item
) 編號,然後是其中的目前行號,item
這樣即使重複日期也sort
可以按順序排序,date
但保留原始輸入順序,然後cut
刪除第一個awk
添加的裝飾品,方便分類。以下是前 2 個步驟的輸出,您可以看到它們的作用:$ awk -f tst.awk file 20210824 1 1 <item> 20210824 1 2 <date>August 24, 2021</date> 20210824 1 3 <p>Text</p> 20210824 1 4 </item> 20210824 1 5 20200211 2 1 <item> 20200211 2 2 <date>February 11, 2020</date> 20200211 2 3 <p>more text</p> 20200211 2 4 </item> 20200211 2 5 20210720 3 1 <item> 20210720 3 2 <date>July 20, 2021</date> 20210720 3 3 <p>some text</p> 20210720 3 4 </item> 20210720 3 5
$ awk -f tst.awk file | sort -k1,1rn -k2,3n 20210824 1 1 <item> 20210824 1 2 <date>August 24, 2021</date> 20210824 1 3 <p>Text</p> 20210824 1 4 </item> 20210824 1 5 20210720 3 1 <item> 20210720 3 2 <date>July 20, 2021</date> 20210720 3 3 <p>some text</p> 20210720 3 4 </item> 20210720 3 5 20200211 2 1 <item> 20200211 2 2 <date>February 11, 2020</date> 20200211 2 3 <p>more text</p> 20200211 2 4 </item> 20200211 2 5