2016-11-09 77 views
1

我有一些機管局SNMP轉儲:從一個shell腳本中提取snmpdump值(用一個確切的MIB)

1.3.6.1.2.1.1.2.0|5|1.3.6.1.4.1.9.1.1178 
    1.3.6.1.2.1.1.3.0|7|1881685367 
    1.3.6.1.2.1.1.4.0|6|"" 
    1.3.6.1.2.1.1.5.0|6|"hgfdhg-4365.gfhfg.dfg.com" 
    1.3.6.1.2.1.1.6.0|6|"" 
    1.3.6.1.2.1.1.7.0|2|6 
    1.3.6.1.2.1.1.8.0|7|0 
    1.3.6.1.2.1.1.9.1.2.1|5|1.3.6.1.4.1.9.7.129 
    1.3.6.1.2.1.1.9.1.2.2|5|1.3.6.1.4.1.9.7.115 

而且需要1.3.6.1.2.1.1.2.0後到grep在第一個字符串的所有數據| 5 |,但不在grep本身中包含該字符串的開始。所以,我必須在grep中收到1.3.6.1.4.1.9.1.1178。我試圖使用正則表達式:

\b1.3.6.1.2.1.1.2.0\|5\|\s*([^\n\r]*) 

但沒有任何成功。如果正則表達式或grep實際上是正確的工具,您能幫我找到正確的正則表達式嗎?否則,我應該考慮什麼工具?

+0

使用帶字段分隔符的awk作爲管道符號並打印出第三個字段,然後將結果傳遞給grep。 – dood

+0

'\ s'和'\ b'是PCRE的擴展。它們在BRE(缺省情況下由'grep'使用)或ERE(與'egrep'或'grep -E'一起使用)中不可用。 –

+1

順便說一句,是否有一個原因,你使用grep而不是awk或sed來完成這項工作? –

回答

3

隨着GNU grep + PCRE的支持,可以使用Perl\K標誌丟棄匹配的字符串的一部分:

grep -Po "1\.3\.6\.1\.2\.1\.1\.2\.0\|5\|\K.*" 

-P使Perl的正則表達式模式和-o輸出切換到匹配部分,而不是整條線。

我不得不逃離那些在Perl中regexs特殊含義的字符,但這樣可以避免爲123表明,通過封閉的字符\Q\E之間字面解釋:

grep -Po "\Q1.3.6.1.2.1.1.2.0|5|\E\K.*" 

我通常用sed來解決這個問題如下:

sed -n 's/1\.3\.6\.1\.2\.1\.1\.2\.0|5|\(.*\)/\1/p' 

-n標誌將禁用隱式輸出,並且搜索和替換命令將從行中刪除搜索到的前綴,並將相關部分打印出來。

必須轉義在GNU基本正則表達式(BRE)中具有特殊含義的字符,在本例中只有.。還要注意,分組標記是\(\)而不是通常的()

+0

只有GNU grep,並且只有編譯了GNU grep的可選PCRE支持版本。 –

+0

@CharlesDuffy謝謝,我提到過,並增加了一個'sed'替代品,我認爲它是可修改的便攜式 – Aaron

+0

LGTM。 –

0

另一種方法是在本地shell中,根本沒有任何正則表達式。試想一下:

prefix='1.3.6.1.2.1.1.2.0|5|' 
while read -r line; do 
    [[ $line = "$prefix"* ]] && printf '%s\n' "${line#$prefix}" 
done 

如果您的原始字符串管道輸送到while read循環,輸出恰恰是1.3.6.1.4.1.9.1.1178

相關問題