Bash

使用 awk 到列的行

  • August 28, 2015

我必須遵循範例輸出:

<HARDWARE>
   <NAME>WIN1</NAME>
   <OS>Windows 7</OS>
   <IP>1.2.3.4</IP>
   <DOMAIN>contoso.com</DOMAIN>
</HARDWARE>
<HARDWARE>
   <NAME>WIN2</NAME>
   <OS>Windows 8</OS>
   <IP>10.20.30.40</IP>
   <DOMAIN>contoso.com</DOMAIN>
</HARDWARE>

解析它的最佳方法是什麼,它看起來像:

WIN1    Windows 7    1.2.3.4     contoso.com
WIN2    Windows 8    10.20.30.40 contoso.com

尋找使用標準工具(如 awk、sed 等)的解決方案

對您的 XML 稍作修改,將所有 XML 包裝在父<DATA>標籤1或您選擇的另一個文件中,文件名為data.xml

<DATA>
<HARDWARE>
   <NAME>WIN1</NAME>
   <OS>Windows 7</OS>
   <IP>1.2.3.4</IP>
   <DOMAIN>contoso.com</DOMAIN>
</HARDWARE>
<HARDWARE>
   <NAME>WIN2</NAME>
   <OS>Windows 8</OS>
   <IP>10.20.30.40</IP>
   <DOMAIN>contoso.com</DOMAIN>
</HARDWARE>
</DATA>

使用xmlstarlet+column

xmlstarlet sel -T -t -m /DATA/HARDWARE -v "concat(NAME,' ',OS,' ',IP,' ',DOMAIN)" -n data.xml | column -t 

給出:

WIN1  Windows  7  1.2.3.4      contoso.com
WIN2  Windows  8  10.20.30.40  contoso.com

編輯:

基於 Peter.O 在評論中的出色表現和他在下面的回答,讓我們將管道分隔的2輸出發送到column -ts$'|',如下所示:

xmlstarlet sel --indent-tab -T -t -m /DATA/HARDWARE -v "concat(NAME,'|',OS,'|',IP,'|',DOMAIN)" -n data.xml | column -ts$'|'

現在,即使它們有空格,這些欄位也可以很好地排列:

WIN1              Windows 7  1.2.3.4 release 5  contoso.com
Really long OS X  Windows 8  10.20.30.40        contoso.com
  1. { echo '<DATA>'; cat file_name; echo '</DATA>'; } | xmlstarlet ... 在下方評論中用作 Peter.O 註釋

  2. 使用空格作為分隔符不能正確對齊列

使用您的範例和 GNU sed:

sed -n 's/<[^>]*>//g;s/^ *//g;/./p' file | paste -d ";" - - - - | column -t -s ";"

輸出:

WIN1 Windows 7 1.2.3.4 contoso.com
WIN2 Windows 8 10.20.30.40 contoso.com

我假設您的文件不包含;. 如果您需要 CSV 刪除| column -t -s ";".

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