私は少し助けを求めて、進行中に学んでいます。以下のようなものがあります。何が起こるのか見せたい「ログイン」Log1から「処理された請求書」ログ1に。検索値の使用 - 44.正直なところ、私はテストのようなものをだまそうとしているように見えますが、そうではありません。私はファイルを分解して学ぶことを望むのが初めてです。
ファイル.txt
Log0 | 20191104 | 01 | Logged In - 55
Log1 | 20191104 | 04 | Logged In - 44
Log2 | 20191104 | 03 | Logged In - 33
Log1 | 20191104 | 02 | Received Bill
Log1 | 20191104 | 02 | Accepted Bill
Log2 | 20191104 | 05 | Logged Out - 33
Log1 | 20191104 | 33 | Processed Bill
Log0 | 20191104 | 44 | Broken Bill
目的の出力を見つけます。
Log1 | 20191104 | 04 | Logged In - 44
Log1 | 20191104 | 33 | Processed Bill
答え1
Perlソリューション:
perl -F'/\|/' -ne '$id = $F[0] if $F[3] =~ /- 44$/;
print if $F[0] eq $id && $F[3] =~ /Logged In|Processed Bill/;
' -- file.txt
-n
入力を1行ずつ読みます。-F
与えられた正規表現の各入力行を配列@F
に分割します。- つまり
$F[3]
、4番目の列が一致すると、- 44
最初の列がに保存されます$id
。 $id
最初の列が同じで、4番目の列がまたはに一致Logged In
する場合は、Processed Bill
行全体を印刷します。
答え2
実際には@Chorobaソリューションと非常によく似ています。
awk -F'|' '/Logged In/ { login[$1]=$0}
/Processed Bill/ && login[$1] { print login[$1]; print}' ex1
どこ:
/Logged In/ { login[$1]=$0}
- 列1に関連付けられている「ログイン」行を保存します(例:「Log1」)。/Processed Bil/ && login[$1] {print ...}
- 以前にログインした「処理済み請求書」が見つかったら印刷します。
修正:44のみ印刷します。
awk -F'|' '/Logged In - 44/ { cod=$1; line=$0}
/Processed Bill/ && $1==cod { print line "\n" $0}' file
答え3
Gnu sedが拡張正規表現モードの場合:
$ sed -re ':a
/Logged In - 44/!d
$d;h;N
/^(\S+)\s*\|.*\n\1\s*\|.*Processed Bill/b
g;ba
' file
結果
Log1 | 20191104 | 04 | Logged In - 44
Log1 | 20191104 | 33 | Processed Bill
どのように動作しますか?
° Skip lines till we meet "Logged In 44"
° Pick up the nexr line and if it is "Processed Bill" AND first field matches with the logged in line, then it's a GO.
° Otherwise, discard the second portion and redo this process.
° Assumption is that logged in 44 line is unique.