検索文字列

検索文字列

次のテキストを含むファイルを検索し、3行目に「Msg 208」の後に「#name not found」がある出力のみをリダイレクトするにはどうすればよいですか?

ファイルテキスト:

[
DBCC upgrade_object: DEFAULT dc_1527463 upgraded successfully.
DBCC upgrade_object: Upgrading PROCEDURE tran_33
DBCC upgrade_object: There's a difference between the objectname tran_33 and the name tran_33 used in syscomments.
DBCC upgrade_object: Maybe the object was renamed using sp_rename.
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.itxxn_33', Line 40:
#old_33 not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
Msg 207, Level 16, State 4:
Server 'DEV_RP', Line 3:
Invalid column name 'eryCmt'.
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
bat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
#wbat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
]

はい - 有効で、出力にキャプチャする必要があります。

{
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.itxxn_33', Line 40:
#old_33 not found. Specify owner.objectname or use sp_help to check whether the object exists 
}

はい - 無効で、出力にキャプチャしないでください。

{
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
bat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
}

ベストアンサー1

空行が偽の編集アーティファクトであると仮定します。

注:input2.txtこれは、不要な改行が削除された入力例の編集済みコピーです。

$ sed -E -e 's/^(Msg |\])/\n\1/; s/\[/[\n/' input2.txt  |
    perl -00 -l -n -e 'print if /^Msg 208.*^#.*not found/ms'
Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.itxxn_33', Line 40:
#old_33 not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).

Msg 208, Level 16, State 1:
Server 'DEV_RP', Procedure 'dbo.yftran_33', Line 40:
#wbat not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).

sedこれは、入力をMsg 各行がまたはの各インスタンスで始まる段落に変換するために使用されます。その後、出力は短絡モード()で入力を読み取るためにパイプされ、短絡を印刷します。[]sedperl-n-00そして、もしこれは正規表現と一致します^Msg 208.*^#.*not found(Perlのm修飾子を使用して各段落を複数行の文字列として処理し、s修飾子を使用して.一致する改行を許可します)。

「段落」は、1つ以上の改行で区切られた1つ以上のテキスト行です。

Perlコマンドラインオプションの詳細man perlrunとPerl正規表現の詳細についてはを参照してくださいman perlre。 Perlスクリプトで正規表現を使用する方法のチュートリアルについては、を参照してくださいman perlretut

からman perlre

m一致する文字列を複数行として扱います。つまり、文字列の最初の行の先頭と最後の行の終わりを一致させることから、文字列のすべての行の先頭と終わりを一致させることに^変更します。$

s文字列を1行として扱います。つまり、.通常は一致しないすべての文字、改行文字まで一致するように変更します。

一緒に使用すると、文字列の改行文字の後ろと前の文字をそれぞれ許可し、一致しながらすべての文字一致を/ms許可します。.^$

ちなみに、これは完全にPerlで実行できますが、sed入力をPerlの短絡モードで簡単に処理できるものに変換する方が簡単で簡単で高速です。

また、btw、中括弧を出力に含めるには、行を次のprint if ...ように変更します。print "{\n$_\n}\n" if ...


元の要求とは逆に印刷します(たとえば、次からMsg 始まる行を含む段落を印刷します)。いいえ含む^Msg 208.*^#.*not foundif ...ステートメントをに変更しますif (/^Msg /ms && ! /^Msg 208.*^#.*not found/ms)。つまり、(読みやすくするための改行とインデントが含まれます):

sed -E -e 's/^(Msg |\])/\n\1/; s/\[/[\n/' input2.txt  |
    perl -00 -l -n -e 'print if (/^Msg /ms && 
                                 ! /^Msg 208.*^#.*not found/ms)'

おすすめ記事