2011-07-05 13 views
1

私は大きなテキストファイルを持っており、今日はSEDの助けを借りて検索と抽出を行っています。 現在のSED scrifpはパターン/文字列を検索し、パターン/文字列からすべての情報を次のスペースに抽出します。文字列を検索して文字列から次の文字列までのすべてを取得

私はただパワーシェルを発見し、それを愛しています。

私はpowershellで同じスクリプトを成功裏に複製しようとしました。 enyoneにはどのように行うべきか提案がありますか?私の現在のテキストファイル(hw.txt)から

例:

i1231 Cisco_1800 *IP=10.10.10.1 *SV=0 *NM=Router_1 *[email protected]_1 
i2385 Cisco_2960 *NM=switch_7 *CM=workstation_switch *IP=192.168.5.97 *SV=1 
i8473 Cisco_PIX *IP=10.10.10.9 *SV=0 *NM=PIX_2 *CM=Int_Firewall 

私の現在のSEDスクリプトを抽出する* IP =と* NM =:

sed -ne "s/^.*\*IP=\([^ ]*\) .*\*NM=\([^ ]*\) .*$/\1 \2/p" -ne "s/^.*\*NM=\([^ ] *\) .*\*IP=\([^ ]*\) .*$/\2 \1/p" db.tmp > hosts 

このスクリプトで発生します

10.10.10.1 Router_1 
192.168.5.97 switch_7 
10.10.10.9 PIX_2 

私は正しい構文を取得する簡単な方法としてこれを使用しようとしました::こと

Select-String ".*\*nm=\([^ ]*\)" hw.txt 

/ピエール

+0

正規表現を翻訳する際の問題は、括弧をエスケープして、リテラルの括弧から括弧(括弧と括弧で囲まれたもの、btw)をキャプチャすることです。他の正規表現のフレーバー。しかし、PowerShellは正規表現の文字通りの翻訳よりもさらに洗練されたソリューションを提供しているので、私はそれを答えとして投稿します。 –

答えて

0

私はこのようにそれを行うだろう:、

まずかかわらず、彼らのために、テキストの行にIPおよびNMテキストを見つける正規表現オブジェクトを作成します。

$regex = [regex] 
    @' 
    (?x)\*IP=(?<IP>\S*).*?\*NM=(?<NM>\S*) # IP first, NM second 
    |          # or 
    \*NM=(?<NM>\S*).*?\*IP=(?<IP>\S*)  # NM first, IP second 
    '@ 

その後、あなたはテキストを反復処理し、抽出することができます:.NETでは、あなたはとても最初に来る2の関係なく、マッチしたテキストが正しいキャプチャグループになり、名前のキャプチャグループを使用することができます値:

$match = $regex.Match($subject) 
while ($match.Success) { 
    IP = $match.Groups['IP'].Value 
    NM = $match.Groups['NM'].Value 
    $match = $match.NextMatch() 
} 
+0

ありがとう!!だから、1ライナーほど簡単ではありません。私はそれを試してみましょう。そして、私はそれを抽出するために別のパターンを追加したい場合、それはかなり簡単だと思われる。 –

+0

申し訳ありませんが、これを動作させることはできません。私はおそらくこれを間違った方法にしています。 @でエラーが発生する。それは '@を見つけることができません。?? hw.txtから情報を取得するにはどうしたらいいですか? Get-content? –

+0

すみません。私はRegexBuddyにPowerShellのコードスニペットを生成させましたが、どこに問題があるのか​​は言えません。コメントなしで試してください:$ regex = [regex] \ * IP =(? \ S *)*?\ * NM =(? \ S *)| \ * NM =(? \ S * )*?\ * IP =(? \ S *) '' - これは現在動作していますか? –

0

これはどう:スペースで

cat test.txt | select @{n='IP';e={[regex]::match($_,'\*IP=([^\s]+)').Groups[1].Value}},@{n='NM';e={[regex]::match($_,'\*NM=([^\s]+)').Groups[1].Value}} 

IP   NM 
--   -- 
10.10.10.1 Router_1 
192.168.5.97 switch_7 
10.10.10.9 PIX_2 

出力に値:

cat test.txt | foreach{ 
    $ip = [regex]::match($_,'\*IP=([^\s]+)').Groups[1].Value 
    $nm = [regex]::match($_,'\*NM=([^\s]+)').Groups[1].Value 
    "{0} {1}" -f $ip,$nm 
} 
+0

これは簡単ではありません。ありがとう! 2つのグループの間にちょうど良い出会いを見つける方法はありますか? –

+0

スレッドを例文 –

+0

で更新しましたありがとうございました! * IP =と* NM =の間でORの代わりにANDを実行するスクリプトを使用できますか? –

関連する問題