次の構成ファイルがあります。
define host{
host_name xxxxxxxx1748
use windows-server
alias Comet
hostgroups +bu-automotiveprd,screen-automotiveprd2
address XXX.XXX.XXX.XXX
}
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
検索したいCPU名、一致するものがある場合、出力は次のようになります。
yyyyyyyyy991
はい - ホストを検索したいとしましょう。
その後、出力は次のようになります。
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
答え1
この試み、
perl -0777 -ne '/([^\n]*{[^}]*(yyyyyyyyy991)[^}]*})/ && print "$1\n"' file
説明する:
perl -0777
Perlを実行し、ファイル全体を1行に読み込みます。-ne
各行(n
)に対してe
次の()操作を実行します。/(pattern)/ && print "$1\n"
正規表現パターンを一致させ、それを最初の一致グループ($1
)として追加してから印刷します。
モデル:
[^\n]*{ ... }
「{」から次の「}」までを含む行の先頭から何でも一致します。- そして
...
存在[^}]*(yyyyyyyyy991)[^}]*
:- そうでないすべての文字と一致します。
}
- どこかに含める必要があります
yyyyyyyyy991
。
- そうでないすべての文字と一致します。
答え2
サポートしている場合は、grep
この-z
オプションを使用してファイル全体を食べさせることができます。
$ grep -ozE 'define[^}]*host_name yyyyyyyyy991.+?}.' file
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
使用されるオプションは次のとおりです(GNUページgrep
から):man
grep
-z, --null-data
Treat input and output data as sequences of lines, each terminated by a
zero byte (the ASCII NUL character) instead of a newline. Like the -Z or
--null option, this option can be used with commands like sort -z to
process arbitrary file names.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line, with each
such part on a separate output line.
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (ERE, see below).
正規表現は、単語define
の後にゼロ個以上の非}
文字([^}]*
)が続く単語を検索し、最初の()と改行文字(最後の文字)に一致する次の文字host_name yyyyyyyyy991
までのすべての項目を検索します。}
.+?
.
しかし、個人的に私はPerlの短絡モードを使って次のことをします。
$ perl -00 -ne 'print if /yyyyyyyyy991/' file
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
入力ファイルが段落として読み取られるため、各レコードは1行ではなく段落(2つの連続した文字として定義されている-00
)であることを示します。これは「各入力レコードを読み、与えられたスクリプトをここに適用する」という意味です。スクリプト自体は、目的のパターンに一致するすべてのレコードを単に印刷します。perl
\n
-ne
-e
答え3
構成ファイルの名前が config.dat で、次のものがあるとします。基準滞在。つまり、yyyyyyyyy991の前には1行だけ、その後には5行しかありません。これにより、このコマンドは目的の出力を取得するのに役立ちます。
grep -B 1 -A 5 "yyyyyyyyy991" config.dat
define host{
host_name yyyyyyyyy991
use aix-server
alias
hostgroups +bu-automotiveprd,screen-automotiveprd2
address YYY.YYY.YYY.YYY
}
~からgrep
男性:
Context control flage:
-B, --before-context=NUM print NUM lines of leading context
-A, --after-context=NUM print NUM lines of trailing context
config.dat ファイルが別のソリューションの場合標準ではないこれは、キーワード "yyyyyyyyy991"がすべてのセクションで同じパターンに従わないことを意味するため、awk
次のようにしたいことができます。
awk -v RS='' '/host_name yyyyyyyyy991/' config.dat
RS =は、入力レコード区切り文字を改行文字から空白行に変更します。レコードのフィールドに/ host_name yyyyyyyyy991 /が含まれている場合は、レコードを印刷します。
RSが空の場合、レコードは1つ以上の空行シーケンスに分けられます。先頭または末尾の空行は、入力の先頭または末尾に空のレコードにしてはいけません。aは、FS Whatに関係なく常にフィールド区切り文字でなければなりません。値です。
出力区切り文字は依然として単一の改行文字であるため、出力段落は区別されません。出力段落の間に空白行があることを確認するには、出力レコード区切り文字を2つの改行に設定します。
答え4
使用sed
:
sed 'H;/^define host{$/h;/^}/{g;/host_name yyyyyyyyy991\n/p};d' file
ステップバイステップ:
H # append line to hold space
/^define host{$/h # start of entry: copy to hold space (overwrites previous content)
/^}/{ # end of entry:
g # retrieve whole entry from hold space
/host_name yyyyyyyyy991\n/p # if host matched, display the whole entry
}
d # no other output