最初、私はこれに対する解決策を得ました。郵便はがき。
ただし、これは2つのモードでのみ利用可能です。これで、2つ以上のパターン、たぶん3番目のパターン、さらには4番目のパターンが必要であることがわかりました。
@casで得られたパターンを追加して、次の解決策を試しました。
awk -v OFS=, '
match($0,/\<[[:digit:]]{1,2}\/[[:digit:]]{1,2}\/[[:digit:]]{4} [[:digit:]]{1,2}:[[:digit:]]{1,2}\>/,a) {dt = a[0]; next};
match($0,/3rd pattern/,b);
match($0,/INC-[[:digit:]]+-[[:digit:]]+/,a) {print a[0], dt; print b[0]}' filename.log
私は次のような結果を得ました。
INC-210305-00000426,3/6/2021 5:19
INC-20210304-00006690,3/5/2021 5:24
スペースを追加するだけです。 3番目または4番目のパターンを見つける方法に関する他の提案はありますか?彼らは実際に別のルートにあります。入力は次のとおりです。
unwantedtext unwantedtext unwantedtext unwantedtext 8/1/2022 6:15 (1st Pattern)
unwantedtext unwantedtext unwantedtext unwantedtext
unwantedtext unwantedtext Report_A (3rd Pattern)
unwantedtext unwantedtext INC-220721-00007628 (2nd required pattern)
unwantedtext unwantedtext unwantedtext unwantedtext
unwantedtext unwantedtext Report_B (4th) Pattern)
希望の出力は次のとおりです。
INC-220721-00007628, 8/1/2022 6:15, Report_A
後で次の出力が必要になる場合があります。
INC-220721-00007628, 8/1/2022 6:15, Report_A, Report_B
私はCygwinとCentOS 7環境を使用しています。
有用な解決策に感謝します。
答え1
perl
代わりに使用しますawk
(gawkも使用します。使用するコードはgawkによって異なります)。
perl -l -0777 -ne '
$time = $& if m{\b\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{1,2}\b};
$inc = $& if /\bINC-\d+-\d+\b/;
@reports = /\bReport_\S+/g;
print join ", ", $inc, $time, @reports
if defined($time) && defined($inc)' your-file
答え2
存在するTxR:
$ txr extract.txr input
INC-220721-00007628, 8/1/2022 6:15, Report_A, Report_B
どこextract.txr
:
@(skip)@{date /[^ ]+/} @{time /[^ ]+/} (1st Pattern)
@(skip)
@(skip)@{rep1 /[^ ]+/} (3rd Pattern)
@(skip)INC-@inccode (2nd required pattern)
@(skip)
@(skip)@{rep2 /[^ ]+/} (4th) Pattern)
@(output)
INC-@inccode, @date @time, @rep1, @rep2
@(end)
行末のパターンを一致させるには、ここにいくつかの正規表現が必要です。テキストキャプチャに似た変数には@date
スペースを含めることができますが、スペースでは@{date /[^ ]+/}
なく一連の文字をキャプチャできます。
出力は1行なので、@(output)
...に含まれるLisp関数呼び出しで置き換えることができます。@(end)
@(do ...)
@(do (put-line `INC-@inccode, @date @time, @rep1, @rep2`))
答え3
POSIX awkを使用してください。
$ cat tst.awk
match($0,/([0-9]{1,2}\/){2}[0-9]{4} [0-9]{1,2}:[0-9]{1,2}/) { dt = substr($0,RSTART,RLENGTH) }
match($0,/INC(-[0-9]+){2}/) { inc = substr($0,RSTART,RLENGTH) }
match($0,/Report_A/) { repa = substr($0,RSTART,RLENGTH) }
match($0,/Report_B/) { repb = substr($0,RSTART,RLENGTH) }
END { OFS=", "; print inc, dt, repa, repb }
$ awk -f tst.awk file
INC-220721-00007628, 8/1/2022 6:15, Report_A, Report_B
上記は、ターゲット正規表現の中間語と一致します。質問の例では、これが可能性としてマークされていませんが、実際のデータに問題がある場合は、次のように変更します。
$ cat tst.awk
function set(val) {
val = substr($0,RSTART,RLENGTH)
gsub(/^ | $/,"",val)
return val
}
match($0,/(^| )([0-9]{1,2}\/){2}[0-9]{4} [0-9]{1,2}:[0-9]{1,2}( |$)/) { dt = set() }
match($0,/(^| )INC(-[0-9]+){2}( |$)/) { inc = set() }
match($0,/(^| )Report_A( |$)/) { repa = set() }
match($0,/(^| )Report_B( |$)/) { repb = set() }
END { OFS=", "; print inc, dt, repa, repb }