Shell-Script

根據日期和月份排列程式碼塊部分

  • August 26, 2021

我有一個像這樣重複內容的文件;

<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

引用自:https://unix.stackexchange.com/questions/666345