(BSD) UNIX 環境では、正規表現を使用して特定の部分文字列をキャプチャしたいと思います。
dmesg
コマンド出力に次の行が含まれているとします。
pass2: <Marvell Console 1.01> Removable Processor SCSI device
<
たとえば、と文字>
の間のテキストをキャプチャしたいと思います。
dmesg | <sed command>
以下を出力する必要があります。
Marvell Console 1.01
ただし、正規表現が一致しない場合は何も出力しないでください。多くのソリューションには、sed -e 's/$regex/\1/
一致するものがない場合に入力全体を出力する機能が含まれていますが、これは私が望むものではありません。
対応する正規表現は次のとおりです。
regex="^pass2\: \<(.*)\>"
sed
正規表現の一致をどのように使用するか、正しく使用しますかgrep
?grep -P
BSD UNIXディストリビューションではこのオプションを使用できません。ただし、sed -E
オプションを使用できます。
答え1
この試み、
sed -nE 's/^pass2:.*<(.*)>.*$/\1/p'
またはPOSIXly(-E
2019年現在のPOSIX規格ではありません):
sed -n 's/^pass2:.*<\(.*\)>.*$/\1/p'
出力:
$ printf '%s\n' 'pass2: <Marvell Console 1.01> Removable Processor SCSI device' | sed -nE 's/^pass2:.*<(.*)>.*$/\1/p'
Marvell Console 1.01
<...>
これにより、各行の最後の項目のみが印刷されます。
答え2
-o
grepで一致する部分だけを印刷するのはどうですか?それでも削除する必要があります<>
が、tr
動作します。
dmesg |egrep -o "<([a-zA-Z\.0-9 ]+)>" |tr -d "<>"
Marvell Console 1.01
答え3
sed、awk、およびPythonを使用して、次の3つの方法を試しました。
sed コマンド
echo "pass2: <Marvell Console 1.01> Removable Processor SCSI device" | sed "s/.*<//g"|sed "s/>.*//g"
出力
Marvell Console 1.01
awkコマンド
echo "pass2: <Marvell Console 1.01> Removable Processor SCSI device" | awk -F "[<>]" '{print $2}'
出力
Marvell Console 1.01
Python
#!/usr/bin/python
import re
h=[]
k=open('l.txt','r')
l=k.readlines()
for i in l:
o=i.split(' ')
for i in o[1:4]:
h.append(i)
print (" ".join(h)).replace('>','').replace('<','')
出力
Marvell Console 1.01
答え4
以下を使用して部分文字列を抽出できますgrep -o -e
。
cat some.log | grep "lineWithThisText" | grep -o -e 'SomeSequence1[0-9]*[A-Z]*SomeSequence2'
何らかの理由で、このgrep regex matchコマンドで1つ以上の一致が*
機能しません。+
以下を使って grep マニュアルをお読みください。
man grep
オプション-o
とについてお読みください-e
。
私は仕事から複数のログラインから大量のデータを抽出するためにそれを使用します。