次の入力ファイルがあります。
Policy Name: KE15-LOCALHOST-APP-RADIX-DAILY
Policy Type: Standard
Active: yes
Include: /appussd
/home/ussd2ke
/var/log
/etc
/usr
Schedule: Montlhy_Full
Type: Full Backup
PFI Recovery: 0
Maximum MPX: 16
Retention Level: 5 (3 months)
Daily Windows:
Sunday 00:00:00 --> Sunday 07:00:00
Monday 00:00:00 --> Monday 07:00:00
Tuesday 00:00:00 --> Tuesday 07:00:00
Wednesday 00:00:00 --> Wednesday 07:00:00
Thursday 00:00:00 --> Thursday 07:00:00
Friday 00:00:00 --> Friday 07:00:00
Saturday 00:00:00 --> Saturday 07:00:00
Schedule: Weekly_Full
Type: Full Backup
PFI Recovery: 0
Maximum MPX: 16
Retention Level: 3 (1 month)
Daily Windows:
Wednesday 00:00:00 --> Wednesday 10:00:00
Schedule: Daily_Inc
Type: Differential Incremental Backup
PFI Recovery: 0
Maximum MPX: 16
Retention Level: 2 (3 weeks)
Daily Windows:
Sunday 01:00:00 --> Sunday 16:00:00
Monday 01:00:00 --> Monday 16:00:00
Tuesday 01:00:00 --> Tuesday 16:00:00
Wednesday 01:00:00 --> Wednesday 16:00:00
Thursday 01:00:00 --> Thursday 16:00:00
Friday 01:00:00 --> Friday 16:00:00
Saturday 01:00:00 --> Saturday 16:00:00
これで、カンマと;で区切られた(計画の下)、保存レベル、毎日のウィンドウなど、さまざまな種類のペアが必要です。複数のアイテムの場合。
私が試したコマンドは次のとおりです。問題は毎日の窓にありました。途中でデータを取得し、毎日のウィンドウ行を削除できました。これで曜日の名前を削除し、一意の期間のみを希望します。
awk '
BEGIN { SEP = "" }
$1 == "Type:" { $1 = ""; T = T SEP $0 }
$1 == "Retention" && $2 == "Level:" {
sub(/^.*\(/," ")
sub(/\).*/,"")
L = L SEP $0
if (SEP == "") {
SEP = ";"
}
}
/Daily Windows:/,/^$/ {
sub(/^.*Daily.*/,"")
sub(/^[^A-Z][a-z]+y$/,"")
S = S SEP $0}
END {
sub(/^ */,"",T)
print T "," L "," S
}'
出力は次のとおりです。
Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks,;; Sunday 00:00:00 --> Sunday 07:00:00; Monday 00:00:00 --> Monday 07:00:00; Tuesday 00:00:00 --> Tuesday 07:00:00; Wednesday 00:00:00 --> Wednesday 07:00:00; Thursday 00:00:00 --> Thursday 07:00:00; Friday 00:00:00 --> Friday 07:00:00; Saturday 00:00:00 --> Saturday 07:00:00;;; Wednesday 00:00:00 --> Wednesday 10:00:00;;; Sunday 01:00:00 --> Sunday 16:00:00; Monday 01:00:00 --> Monday 16:00:00; Tuesday 01:00:00 --> Tuesday 16:00:00; Wednesday 01:00:00 --> Wednesday 16:00:00; Thursday 01:00:00 --> Thursday 16:00:00; Friday 01:00:00 --> Friday 16:00:00; Saturday 01:00:00 --> Saturday 16:00:00
ただし、希望の出力は次のとおりです。
Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks, 00:00:00 --> 07:00:00; 00:00:00 --> 10:00:00; 01:00:00 --> 16:00:00
答え1
:
オプションのコロンとFS()で少なくとも2つのスペースを使用すると、余分なスペースと呼ばれる面倒なFS = ":? *"
問題を経験することなく、この操作に使用される主なフィールドのほとんどを分離できるようになります。
$ cat t20.awk
BEGIN { FS=":? *"; OFS = ", "; SEP = "; "; }
# if $2 is "Type", append $3 to T
$2 == "Type" { T = (T ? T SEP : "") $3;}
# if $2 is "Retention Level", append sub-string in parenthesis to L
$2 == "Retention Level" && match($0, /\(.*?\)/) {
L = (L ? L SEP : "") substr($0, RSTART+1, RLENGTH-2)
}
# in Daily window block, skip all line without " --> "
# use an associative array "a" to make sure unique time range
/Daily Windows:/,/^\s*$/ {
if (!/ --> /) next
key = $3 " --> " $6
if (!a[key]++) S = (S ? S SEP : "") key
}
END { print T, L, S }
メモ:
では、接続の場合と同様に、文字列を連結するときに先行するSEPを回避するために
S = (S ? S SEP : "") key
トリプルを(S ? S SEP : "")
使用します。T
L
では、削除先行を
substr($0, RSTART+1, RLENGTH-2)
使用し、両方の角かっこを削除します。RSTART+1
(
RLENGTH-2
コードを実行してください:
$ awk -f t20.awk file.txt
#Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks, 00:00:00 --> 07:00:00; 00:00:00 --> 10:00:00; 01:00:00 --> 16:00:00
修正する:
コメントに記載されている内容に基づいて、Daily Windows
コードのこの部分を次のように調整しました。
- ロゴを追加しましたdw_on開始と終了を識別するために毎日の窓詰まった。
dw_on == 1
このパターンで一致するすべての行を確認する必要があります。次の空行が検出されるたびに、このフラグは次にリセットされます。/ --> /
S
0
/^\s*$/
- 変数を追加しましたcnt_DW数量を計算する毎日の窓各スケジュールの項目です。これは
Daily Windows
各ブロックの開始時にリセットされます。
ハッシュ(連想配列)によって一意性が維持されます。ㅏ、各ブロックが起動するとリセットされますDaily Windows
。このハッシュのキーはkey = $3 " --> " $6
検索したいウィンドウです。構文:if (!a[key]++) S = (S ? S SEP : "") key
以下と同じ
if (!a[key]) {
a[key] = a[key] + 1
S = (S ? S SEP : "") key
}
したがって、(a [key] = "")以前に見たことがない場合にのみ、キーkey
にaを追加できますS
。 2番目にすでに存在する同じキーを処理すると、上記a[key]==1
のコードブロックはスキップされます。これはawk
一意性を検証する一般的な方法の1つです。
$ cat t20.1.awk
BEGIN { FS=":? *"; OFS = ", "; SEP = "; "; }
# if $2 is "Type", append $3 to T
$2 == "Type" { T = (T ? T SEP : "") $3;}
# if $2 is "Retention Level", append sub-string in parenthesis to L
$2 == "Retention Level" && match($0, /\(.*?\)/) {
L = (L ? L SEP : "") substr($0, RSTART+1, RLENGTH-2)
}
/Daily Windows:/ {
# turn on the dw_on flag and reset cnt_DW (number of DW entries in a section)
dw_on = 1; cnt_DW=0;
# reset the hash 'a' for uniqueness check
# if you need the uniqueness across all Schedules, then comment it out
delete a;
next;
}
# if dw_on flag is true, i.e. "dw_on == 1"
dw_on {
# match " --> ", then increase cnt_DW, check the unique window
# and then append qualified entry to "S"
if (/ --> /) {
cnt_DW++
key = $3 " --> " $6
if (!a[key]++) S = (S ? S SEP : "") key
# else if EMPTY line, reset dw_on flag, if cnt_DW is 0, append "No Window" to S
} else if (/^\s*$/) {
dw_on = 0;
if (!cnt_DW) S = (S ? S SEP : "") "No Window"
}
}
END {
# last Schedule section does not have a EMPTY line, so we will need
# to check up cnt_DW in the last Schedule section in "END" block
if(dw_on && !cnt_DW) S = (S ? S SEP : "") "No Window";
# print the result.
print T, L, S
}
上記のコードをテストするために、元のデータを次のように少し変更しました。
Daily Windows
Schedule
Part IIから別のアイテムを削除しました。Friday 00:00:00 --> Friday 07:00:00
最初のスケジュールの行をFriday 01:00:00 --> Friday 16:00:00
3 番目のスケジュールセクションの同じ行に置き換えます。
したがって、1日目には固有窓が2つあり、2日程には窓がなく、3日程には固有窓が1つがあり、1日頂窓と同じです。
上記のデータで更新されたコードを実行すると、次のような結果が得られます。
awk -f t20.1.awk file.txt
#Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks, 00:00:00 --> 07:00:00; 01:00:00 --> 16:00:00; No Window; 01:00:00 --> 16:00:00
01:00:00 --> 16:00:00
異なるタイムラインにあるため、2つがあることに注意してください。最後のエントリを削除するには、コードに表示されている行を01:00:00 --> 16:00:00
コメントアウトすると、次のような結果が得られます。delete a
#Full Backup; Full Backup; Differential Incremental Backup, 3 months; 1 month; 3 weeks, 00:00:00 --> 07:00:00; 01:00:00 --> 16:00:00; No Window
答え2
次の操作ですべての操作を実行できますawk
。
awk -F'(: *|[)(])' '
/^ *Type/ { type=type==""?$2 : type ";" $2 }
/^ *Retention/{ Retention=Retention==""?$3 : Retention ";" $3}
/^ *Wednesday/{ gsub(/ +Wednesday/,"",$0); day=day==""?$0 : day ";" $0}
END{ print type, Retention, day }' OFS=, infile
/ ... /
フィールド値をより正確に一致させるには、基準セクションを調整する必要があります。
出力は期待どおりです。