[英]Using Sed Awk Bash to populate variable in search
我有幾個包含多個部分的xml文件。 這些文件中的部分之一是“ PublishMgr”。 在本節下面,有兩行包含服務器名稱和端口。 我需要提取服務器和端口,並將它們放入變量並針對它們運行查詢。 我真的不知道有什么簡單的方法可以做到這一點。 我當時在考慮使用awk和sed,但是我對這些知識的了解是有限的。 你能幫忙嗎?
我已經盡力將線條打印出來。 我可以使用awk -F獲取第一個條目的主機名和端口號,但不確定第二行如何做? 如果可能,我希望一次掃描,而不是兩次查詢? 能做到嗎?
請注意,我要將輸出分配給4個不同的變量!
我的密碼
cat filename | grep -A6 PublishMgr | grep "Address\|BacKMeUp"
XML-FILE / TXT僅文件的一部分
<<!--==========================================-->
<!-- PublishMgr -->
<!--==========================================-->
<goandpublishme>
<ClassPub name="buylimit" pers="Y">
<prime>host9:1000</prime>
<backup>host145:9999</backup>
</ClassPub>
電流輸出
<prime>host9:1000</prime>
<backup>host145:9999</backup>
想要將結果分配給變量的所需輸出請注意,我想將輸出分配給4個“不同”變量。 因此,我可以將它們用於進一步的查詢,就像一個簡單的示例將是cd abc / $ srv1; grep ports $ srv1.log。 簡而言之,我需要有$ srv1 $ srv2 $ port1 $ port2
srv1=host9
port1=1000
srv1=host145
port2=9999
這直接滿足您所需的輸出,並且基於您說您對sed和awk的了解有限的事實。
如果這是您當前的輸出
<prime>host9:1000</prime>
<backup>host145:9999</backup>
然后,您可以通過添加帶有多個表達式的sed命令並遍歷行匹配項列表來獲得所需的輸出:
| sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g" -e "s/(<.[^>]*>)//g" -e "s/(:)/\nport$i=/g"
細分如下:
-e "s/(^\\s*)(<.[^>]*>)/srv$i=/g"
(^\\s*)
-行首,后跟無限制的空格 (<.[^>]*>)
-這些<>
以及中間的任何內容 /srv$i=/g
替換為srv,后跟增量編號。 -e "s/(<.[^>]*>)//g"
刪除前導空格
-e "s/(:)/\\nport=/g"
用\\n
(換行)和port=
替換:
input.txt
,其中包含: <<!--==========================================-->
<!-- PublishMgr -->
<!--==========================================-->
<goandpublishme>
<ClassPub name="buylimit" pers="Y">
<prime>host9:1000</prime>
<backup>host145:9999</backup>
</ClassPub>
prime backup
遍歷行匹配列表
i=1 ; for predicate in prime backup ; do grep -P "$predicate" <input.txt | sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g" -e "s/(<.[^>]*>)//g" -e "s/(:)/\nport$i=/g" ; (( i++ )) ; done
結果:
srv1=host9
port1=1000
srv2=host145
port2=9999
OLDIFS="$IFS" ; IFS=$'\n' ; for line in "$(i=1 ; for predicate in prime backup ; do grep -P "$predicate" <input.txt | sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g" -e "s/(<.[^>]*>)//g" -e "s/(:)/\nport$i=/g" ; (( i++ )) ; done)" ; do eval "$line" ; done ; IFS="$OLDIFS"
分解:
#!/bin/bash
OLDIFS="$IFS" #Save current IFS just for good measure
IFS=$'\n' #Set IFS to new-line
for line in "$(i=1
for predicate in prime backup
do grep -P "$predicate" <input.txt \
| sed -E -e "s/(^\s*)(<.[^>]*>)/srv$i=/g"\
-e "s/(<.[^>]*>)//g" \
-e "s/(:)/\nport$i=/g"
(( i++ ))
done)" #The original script broken into lines
do
eval "$line" #Actually assign the variables
done
IFS="$OLDIFS" #Restore IFS
echo "\$srv1 is: $srv1" #Print values of assigned variables
echo "\$srv2 is: $srv2"
echo "\$port1 is: $port1"
echo "\$port2 is: $port2"
通常,您不應使用sed
和awk
等面向行的工具來處理XML數據。 您應該改為使用支持XML的工具。 假設您的文檔確實是有效的XML,則可以使用xmlstarlet
提取信息:
xmlstarlet sel -t -v 'concat("srv1=", substring-before(//ClassPub/prime, ":"))' -nl \
-t -v 'concat("port1=", substring-after(//ClassPub/prime, ":"))' -nl publish.xml
只需將prime
替換為backup
然后相應地調整字符串即可。 我懷疑您可能是說srv2
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.