2010-11-02 109 views
0

我对此非常有如下的文件:不存在SED解析值似乎行为不一致

bash$ cat blah.txt 
<smsDeliveryStatus value="Provider Malfunction"/> 
<smsDeliveryStatus value="Provider Malfunction" id="23434"/> 
<smsDeliveryStatus value="Delivery Failure"/> 
<smsDeliveryStatus value="Delivery Successful" id="2"/> 
bash$ 

我想提取从每行的文件的价值和功能ID和任一值或ID不存在我想打印未知。我写了下面的代码,这似乎失败了一些时间设置ID未知和一些失败的时间:

bash$ cat blah.txt | sed -nr "/smsDeliveryStatus /{h; /value/ {s/.*value=\"([^\"]*)?\".*/value: \1/}; /value/! {s/.*/value: Unknown/}; p; x; /id/ {s/.*id=\"([^\"]+)\".*/id: \1/g}; /id/! {s/.*/id: Unknown/g}; p}" 

这就产生了从上述文件中的下列结果:

value: Provider Malfunction 
<smsDeliveryStatus value="Provider Malfunction"/> 
value: Provider Malfunction 
id: 23434 
value: Delivery Failure 
id: Unknown 
value: Delivery Successful 
id: 2 

奇怪的是,缺少id的第一行被完整地打印出来,第二行的id缺少将id设置为未知的预期。任何人都可以阐明为什么会发生这种情况?第一次/ id /!有什么区别?被阅读和第二次?

一个

回答

0

我加入多行的文件,像这样:

bash$ cat blah.txt 
<smsDeliveryStatus value="Provider Malfunction"/> 
<smsDeliveryStatus value="Provider Malfunction" id="23434"/> 
<smsDeliveryStatus value="Delivery Failure"/> 
<smsDeliveryStatus value="Delivery Successful" id="2"/> 
<smsDeliveryStatus value="Provider Malfunction"/> 
<smsDeliveryStatus value="Delivery Failure"/> 
<smsDeliveryStatus value="Delivery Successful" id="2"/> 
<smsDeliveryStatus value="Provider Malfunction" id="23434"/> 
<smsDeliveryStatus value="Delivery Failure"/> 
<smsDeliveryStatus value="Provider Malfunction"/> 
bash$ 

当我再次运行代码,我得到了以下内容:

bash$ cat blah.txt | sed -nr "/smsDeliveryStatus /{h; /value/ {s/.*value=\"([^\"]*)?\".*/value: \1/}; /value/! {s/.*/value: Unknown/}; p; x; /id/ {s/.*id=\"([^\"]*)\".*/id: \1/g}; /id/! {s/.*/id: Unknown/g}; p}" 
value: Provider Malfunction 
<smsDeliveryStatus value="Provider Malfunction"/> 
value: Provider Malfunction 
id: 23434 
value: Delivery Failure 
id: Unknown 
value: Delivery Successful 
id: 2 
value: Provider Malfunction 
<smsDeliveryStatus value="Provider Malfunction"/> 
value: Delivery Failure 
id: Unknown 
value: Delivery Successful 
id: 2 
value: Provider Malfunction 
id: 23434 
value: Delivery Failure 
id: Unknown 
value: Provider Malfunction 
<smsDeliveryStatus value="Provider Malfunction"/> 
bash$ 

害得我一看就知道所有不匹配的行都在其中包含字母id,因此我使用围绕id的\ b单词边界来解决此问题,如下所示:

bash$ cat blah.txt | sed -nr "/smsDeliveryStatus /{h; /value/ {s/.*value=\"([^\"]*)?\".*/value: \1/}; /value/! {s/.*/value: Unknown/}; p; x; /\bid\b/ {s/.*id=\"([^\"]*)\".*/id: \1/g}; /\bid\b/! {s/.*/id: Unknown/g}; p}" 
value: Provider Malfunction 
id: Unknown 
value: Provider Malfunction 
id: 23434 
value: Delivery Failure 
id: Unknown 
value: Delivery Successful 
id: 2 
value: Provider Malfunction 
id: Unknown 
value: Delivery Failure 
id: Unknown 
value: Delivery Successful 
id: 2 
value: Provider Malfunction 
id: 23434 
value: Delivery Failure 
id: Unknown 
value: Provider Malfunction 
id: Unknown 
bash$ cat blah.txt 

所以最后我自己解决了。我希望这可以帮助别人。

一个

+2

我希望与像XML的语言打交道时,你可能会考虑其他的选择,而不是扔在他们的正则表达式。 – Joey 2010-11-02 09:55:55

+0

我愿意。我使用python xml.sax来解析我的xml,但我也想用sed和awk来检查我自己的个人学习体验 – amadain 2010-11-02 10:11:17