我正在寻求一点帮助,我正在边走边学习。我有类似于下面的内容。我希望显示发生的情况“登录”在 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
逐行读取输入-F
将给定正则表达式上的每个输入行拆分到@F
数组中- 如果
$F[3]
,即第四列,匹配- 44
,则第一列存储在 中$id
。 $id
如果第一列等于且第四列匹配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.