使用sed在无限行上匹配regex,并将匹配的结果转储到另一个文件中
上面是日志的一部分,我想从中获取“stripe\u card\u token”的值。但只有满足以下条件,使用sed在无限行上匹配regex,并将匹配的结果转储到另一个文件中,regex,awk,sed,Regex,Awk,Sed,上面是日志的一部分,我想从中获取“stripe\u card\u token”的值。但只有满足以下条件, 获取包含“RegistrationController#create”的行的进程ID(上例中为1140) 从第二次出现流程ID(#1140)的行中获取“tok.*.”(上例中的第二行) 如果进程ID第四次出现(#1140)的行包含“已完成200 OK”(上例中的最后一行),则将上述“tok.*.”写入文件 我尝试了grep,但我没有这样做,然后尝试了awk,了解到它不支持反向引用,然后现在我
I, [2014-05-06T06:41:40.742048 #1140] INFO -- : Processing by RegistrationsController#create as */*
I, [2014-05-06T06:41:40.742246 #1140] INFO -- : Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "user"=>{"firstname"=>"...", "lastname"=>"...", "userdetail"=>{"company_name"=>"..."}, "email"=>"...", "confirm_email"=>"...", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "userdetail"=>{"stripe_card_token"=>"tok_103z0G2C7pqlpkF2EMnce0fP", "ccName"=>"...", "ccNumber"=>"[FILTERED]", "ccCode"=>"[FILTERED]", "street_address1"=>"...", "street_address2"=>"", "city"=>"...", "state_code"=>"...", "zipcode"=>"...", "country_code"=>"..."}, "date"=>{"month"=>"..", "year"=>".."}}
D, [2014-05-06T06:41:40.745900 #1140] DEBUG -- : ^[[1m^[[36mActiveRecord::SessionStore::Session Load (1.2ms)^[[0m ^[[1mSELECT `sessions`.* FROM `sessions` WHERE `sessions`.`session_id` = 'a7fcdd2176e490998cf0b85a71f4f0d5' ORDER BY `sessions`.`id` ASC LIMIT 1^[[0m
I, [2014-05-06T06:41:40.783411 #1127] INFO -- : Started GET "/invoices/067c84a2-f40e-47dc-bacc-08a48e5cc72e" for 201.102.245.18 at 2014-05-06 06:41:40 +0000
I, [2014-05-06T06:41:40.787649 #1127] INFO -- : Processing by InvoicesController#show as HTML
I, [2014-05-06T06:41:40.787746 #1127] INFO -- : Parameters: {"uid"=>"067c84a2-f40e-47dc-bacc-08a48e5cc72e"}
D, [2014-05-06T06:41:40.794223 #1127] DEBUG -- : ^[[1m^[[35mActiveRecord::SessionStore::Session Load (1.0ms)^[[0m SELECT `sessions`.* FROM `sessions` WHERE `sessions`.`session_id` = 'f7b35a977fe056dc37bf8f296daa1a9b' ORDER BY `sessions`.`id` ASC LIMIT 1
D, [2014-05-06T06:41:40.952192 #1127] DEBUG -- : ^[[1m^[[35mCACHE (0.0ms)^[[0m SELECT `statuses`.* FROM `statuses` WHERE `statuses`.`id` = 17 ORDER BY `statuses`.`id` ASC LIMIT 1 [["id", 17]]
I, [2014-05-06T06:41:40.994466 #1127] INFO -- : Completed 200 OK in 207ms (Views: 75.1ms | ActiveRecord: 119.3ms)
D, [2014-05-06T06:41:40.995972 #1127] DEBUG -- : ^[[1m^[[36m (0.8ms)^[[0m ^[[1mBEGIN^[[0m
D, [2014-05-06T06:41:40.997475 #1127] DEBUG -- : ^[[1m^[[35m (0.7ms)^[[0m COMMIT
I, [2014-05-06T06:41:41.813041 #1140] INFO -- : Completed 200 OK in 1070ms (Views: 0.8ms | ActiveRecord: 1.2ms)
我想如果注册控制器create的参数中有tok#U id,那么上面的代码会给我。。为了检查已完成的200,我必须修改第三个表达式。有人知道正确的方法吗?这里有一个awk版本,它可以通过日志文件三次
gettoken.awk
:
sed -ne '/[[:digit:]]+]/{h;p}
/RegistrationsController#create/p
/tok_.*",/{h;p}' file
用法:
BEGIN {
count=0;
}
# First pass through file
NR==FNR{
if (index($0,"RegistrationsController#create") > 0) {
pid=substr($3,2,length($3)-2);
}
recordcount=NR;
}
# Second pass through file
NR==recordcount+FNR{
if (index($3,pid)==2) {
count=count+1
if (count==4 && index($0,"Completed 200 OK" > 0)) {
success=1;
}
}
}
# Final pass through file
/stripe_card_token/{
if (index($3,pid)==2 && success==1) {
match($0,/(tok_[A-Za-z0-9]*)/);
token=substr($0,RSTART,RLENGTH);
}
}
END{
print pid, count, success, token;
}
data | sed-E'/regex/'
Awk显然是一种图灵完整编程语言。诀窍是不要试图在一个正则表达式中实现它。“检查第四次出现的行”听起来是否健壮。您希望从成功的事务中收集令牌,对吗?在两种情况下,都返回Completed 200,即成功/不成功的事务。如果交易不成功,则第四次出现的流程ID包含“Completed 200”,否则在获得“Completed 200”之前,流程ID可能会出现25/30左右。我无法完全理解上述脚本,但据我所知,如果第四次出现的进程ID不包含“Completed 200 OK”,则它不会在整个文件中循环。它只是停止并打印“pid 0”。如何使其搜索整个文件?在第二次遍历文件时,将检查每个记录。如果给定记录的pid
正确,它将检查“Completed 200 OK”,并将该事实保存在success
变量中。如果第四次出现的pid
不包含该字符串,则它会不断增加该pid
后续每次出现的计数。如果pid
为0,那是因为脚本在第一次遍历文件时找不到它。ohh ok,那么它会搜索整个文件,并找到第一个pid?完成第一个pid后,不要检查文件中的下一个pid?我不知道会有多个pid。您可以将脚本更改为使用pid数组(以及相应的计数、成功和令牌数组)。你需要帮忙吗?
awk -f gettoken.awk logfile logfile logfile