Shell

使用 xmllint 解析 XML 並自定義輸出

  • July 10, 2021

我有以下架構的 xml 文件(比如 input.xml):

<?xml version="1.0"?>
 <TagA>
   <TagB>
     <File Folder="FOLDER1M\1" File="R1.txt" />
   </TagB>
   <TagB>
     <File Folder="FOLDER1M\2" File="R2.txt" />
   </TagB>
   <TagB>
     <File Folder="FOLDER2M\1" File="R3.txt" />
   </TagB>
 </TagA>

我需要解析這個文件並將輸出寫入另一個文件。所需的輸出應採用以下形式:

www.xyz.com\FOLDER1M\1\R1.txt
www.xyz.com\FOLDER1M\2\R2.txt
www.xyz.com\FOLDER2M\1\R3.txt

到目前為止,我得到的是:

echo 'cat /TagA/TagB/File/@*[name()="Folder" or name()="File"]' | xmllint --shell input.xml | grep '=' > xml_parsed

這給了我 o/p 的形式:

/ > cat /TagA/TagB/File/@*[name()="Folder" or name()="File"]
Folder="FOLDER1M\1"
File="R1.txt"
Folder="FOLDER1M\2"
File="R2.txt"
Folder="FOLDER2M\3"
File="R3.txt"

我應該如何獲取所需的輸出而不是目前的 o/p?

這是一種方法。我只是將您的輸出放入一個名為 sample.txt 的文件中以使其更易於測試,您只需將我的命令附加到 echo 命令的末尾即可:

樣本.txt

Folder="FOLDER1M\1"
File="R1.txt"
Folder="FOLDER1M\2"
File="R2.txt"
Folder="FOLDER2M\3"
File="R3.txt"

命令

% cat sample.txt | sed 'h;s/.*//;G;N;s/\n//g' | sed 's/Folder=\|"//g' | sed 's/File=/\\/' | sed 's/^/www.xyz.com\\/'

命令分解

將每 2 行連接在一起

# sed 'h;s/.*//;G;N;s/\n//g'
Folder="FOLDER1M\1"File="R1.txt"
Folder="FOLDER1M\2"File="R2.txt"
Folder="FOLDER2M\3"File="R3.txt"

刪除文件夾=&“

# sed 's/Folder=\|"//g'
FOLDER1M\1File=R1.txt
FOLDER1M\2File=R2.txt
FOLDER2M\3File=R3.txt

將 File= 替換為 ‘'

# sed 's/File=/\\/'
FOLDER1M\1\R1.txt
FOLDER1M\2\R2.txt
FOLDER2M\3\R3.txt

插入 www.xyz.com

# sed 's/^/www.xyz.com\\/'
www.xyz.com\FOLDER1M\1\R1.txt
www.xyz.com\FOLDER1M\2\R2.txt
www.xyz.com\FOLDER2M\3\R3.txt

編輯#1

OP 更新了他的問題,詢問如何修改我的答案以刪除第一行輸出,例如:

/ > cat /TagA/TagB/File/@*[name()="Folder" or name()="File"]
...
...

我向他提到,您可以使用它grep -v ...來過濾掉不相關的行,如下所示:

% cat sample.txt | grep -v "/ >" | sed 'h;s/.*//;G;N;s/\n//g' | sed 's/Folder=\|"//g' | sed 's/File=/\\/' | sed 's/^/www.xyz.com\\/'

此外,要將整個位寫入文件,可以這樣做:

% cat sample.txt | grep -v "/ >" | sed 'h;s/.*//;G;N;s/\n//g' | sed 's/Folder=\|"//g' | sed 's/File=/\\/' | sed 's/^/www.xyz.com\\/' > /path/to/some/file.txt

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