"db-unique-name"
が含まれるlifecycle-state": "AVAILABLE"
の検索についてサポートが必要です。
cat db_systems.txt
"db-unique-name": "p00z5bj_iad2bj",
"db-workload": "OLTP",
"defined-tags": {},
"freeform-tags": {},
"id": "dfadfasfsadfasdfasdf",
"lifecycle-details": null,
"lifecycle-state": "AVAILABLE",
--
"db-unique-name": "p00u5bh_iad2bj",
"db-workload": "OLTP",
"defined-tags": {},
"freeform-tags": {},
"id": "asdfsadfasdfasfd",
"lifecycle-details": "Resource was terminated at the backend.",
"lifecycle-state": "FAILED",
--
"db-unique-name": "p00u5bh_iad2bj",
"db-workload": "OLTP",
"defined-tags": {},
"freeform-tags": {},
"id": "asdfasdfasdf",
"lifecycle-details": "Resource was terminated at the backend.",
"lifecycle-state": "FAILED",
enter code here
"db-unique-name"
に基づいて"lifecycle-state": "AVAILABLE"
の値を試しました。次、しかしそれは間違った値を与えます
cat db_systems.txt | egrep -A -6 "lifecycle-state|AVAILABLE" | grep db-unique-name
"db-unique-name": "p00u5bh_iad2bj",
"db-unique-name": "p00u5bh_iad2bj",
私もこれを試しましたが、すべてがリストされています
cat db_systems.txt | awk -F";" '{for(i=1;i<=NF;i++){if ($i ~ /AVAILABLE|db-unique-name/){print $1}}}' | grep db-unique-name
"db-unique-name": "p00z5bj_iad2bj",
"db-unique-name": "p00u5bh_iad2bj",
"db-unique-name": "p00u5bh_iad2bj",
これを試して、
grep
の使用:
grep -B6 AVAILABLE file | grep db-unique-name
"db-unique-name": "p00z5bj_iad2bj",
B
行を一致させる前に、先行コンテキストのNUM行を印刷します。awk
の使用:
awk '{a[++i]=$0;}/AVAILABLE/{print a[NR-6];}' file
"db-unique-name": "p00z5bj_iad2bj",
GNU awk
:
awk -F',' 'BEGIN { RS = "--" } /"lifecycle-state": "AVAILABLE"/ { gsub("^[[:blank:]]*", "", $1); print $1 }' file
出力:
"db-unique-name":"p00z5bj_iad2bj"
JSON形式のデータを処理している場合(フラグメントはそのように見えます)、そのようなデータに非常に役立つツールであるjq
を確認する必要があります。
データが次のようになっている場合
{
"db-unique-name": "p00z5bj_iad2bj",
"db-workload": "OLTP",
"defined-tags": {},
"freeform-tags": {},
"id": "dfadfasfsadfasdfasdf",
"lifecycle-details": null,
"lifecycle-state": "AVAILABLE"
}
{
"db-unique-name": "p00u5bh_iad2bj",
"db-workload": "OLTP",
"defined-tags": {},
"freeform-tags": {},
"id": "asdfsadfasdfasfd",
"lifecycle-details": "Resource was terminated at the backend.",
"lifecycle-state": "FAILED"
}
{
"db-unique-name": "p00u5bh_iad2bj",
"db-workload": "OLTP",
"defined-tags": {},
"freeform-tags": {},
"id": "asdfasdfasdf",
"lifecycle-details": "Resource was terminated at the backend.",
"lifecycle-state": "FAILED"
}
次に、このjq
ステートメント
jq 'select(."lifecycle-state" == "AVAILABLE") | ."db-unique-name" ' < db_systems.txt
出力されます
"p00z5bj_iad2bj"
ただし、ファイルが実際に指定した例のようである場合(--
は区切り文字であり、{}オブジェクト表記はありません)awk
ソリューションの方が簡単かもしれません。
これはうまくいくはずです:
$ awk '$1=="\"db-unique-name\":"{name=$2}
$1=="\"lifecycle-state\":" && $2 ~ /AVAILABLE/ {print name}' systems.txt
"p00z5bj_iad2bj",
または、db-unique-name
行、試してください:
$ awk '$1=="\"db-unique-name\":"{name=$0}
$1=="\"lifecycle-state\":" && $2 ~ /AVAILABLE/ {print name}' systems.txt
"db-unique-name": "p00z5bj_iad2bj",
これらがJSONデータの抽出である場合は、それらをJSONにラップして、JSONツールを使用します。
{ echo '{'; sed 's/^ *-- *$/"": ""} {/' db_systems.txt; echo '"": ""}'; } |
jq 'select(."lifecycle-state" == "AVAILABLE") | ."db-unique-name" '
(jq
query by Hans-Martin Mosner )
最初に配列を作成するこのアプローチでは、f[]
以下では、各要素の名前をその値にマップし、その名前ですべてのフィールドにアクセスできるため、複雑な条件を作成し、フィールドを任意の順序で出力します。
$ cat tst.awk
{
gsub(/^[[:space:]]*"|"?,[[:space:]]*$/,"")
tag = val = $0
sub(/".*$/,"",tag)
sub(/.*"/,"",val)
f[tag] = val
}
/^--/ { prt() }
END { prt() }
function prt() {
if ( f["lifecycle-state"] == "AVAILABLE" ) {
print f["db-unique-name"]
}
delete f
}
$ awk -f tst.awk file
p00z5bj_iad2bj
例えば:
$ cat tst.awk
BEGIN { OFS="," }
{
gsub(/^[[:space:]]*"|"?,[[:space:]]*$/,"")
tag = val = $0
sub(/".*$/,"",tag)
sub(/.*"/,"",val)
f[tag] = val
}
/^--/ { prt() }
END { prt() }
function prt() {
recNr++
if ( (f["lifecycle-state"] == "FAILED") || ( (f["db-unique-name"] ~ /bh/) && (f["db-workload"] == "OLTP") ) ) {
print recNr, f["lifecycle-details"], f["id"], f["db-unique-name"]
}
delete f
}
$ awk -f tst.awk file
2,Resource was terminated at the backend.,asdfsadfasdfasfd,p00u5bh_iad2bj
3,Resource was terminated at the backend.,asdfasdfasdf,p00u5bh_iad2bj
Db-unique-nameフィールドとlifecycle-stateフィールドが必須であり、常に同じ順序で出力されると想定します(ただし、間に正確に5行あるとは限りません)。
cat db_systems.txt \
| grep -E '"(db-unique-name|lifecycle-state)":' \
| grep -B 1 '"AVAILABLE"' \
| grep db-unique-name \
| cut -d\" -f4
xargs
、while read name
などにパイプするのに最適です。
これは役に立ちます。
grep -B 6 AVAILABLE db_systems.txt | grep db-unique-name
これは機能します:
grep -e db-unique-name -e lifecycle-state.*AVAILABLE < filename | grep -B1 lifecycle-state.*AVAILABLE | grep db-unique-name
-B6
を使用する場合とは異なり、これは対象の2行の間に6行あることを想定していません。
(もちろん、他の多くの応答はjq
を使用することを正しく提案しています。これは間違いなくより良いオプションです)。