如何在 Linux 系统中从文本文件中提取以下值/字段:
EventCorrelationId="615-493|-1899671563||1550927718000"
CreationTime="20190225094504"
SubscriberNumber=92705073362
文本文件样本数据如下:
2019-02-25 09:45:04.427 FAIL RETRY: Failed for request id: 11235993 Cause: userNotReachable Info: <undef> Code: 27,USSD RequestId=11235993 OriginalId=11235993 EventCorrelationId="615-493|-1899671563||1550927718000" CreationTime="20190225094504" ResendCount=0 Timestamp=1551071704342 (Mon Feb 25 09:45:04 AFT 2019) State=STATE_SENT SubscriberNumber=92705073362 UssdText=Last event was charged 687.95 MB from 3GB Monthly, Main Account 6.00 PKR, Remaining data 2,388.75 MB (Exp 25.03.2019), Main Account 7.62 PKR1500 PKR = 32GB valid 30 Days, Dial *477*32*1#. NumberingPlan=1 Nadi=4 UssdFormat=2
答案1
使用 grep
$ grep -oE '(EventCorrelationId|CreationTime|SubscriberNumber)[^ ]*' textfile
EventCorrelationId="615-493|-1899671563||1550927718000"
CreationTime="20190225094504"
SubscriberNumber=92705073362
使用 awk
尝试:
$ awk -v RS=' ' '/^EventCorrelationId=/ || /^CreationTime=/ || /^SubscriberNumber=/' textfile
EventCorrelationId="615-493|-1899671563||1550927718000"
CreationTime="20190225094504"
SubscriberNumber=92705073362
怎么运行的
-v RS=' '
这告诉 awk 使用空格作为记录分隔符。
/^EventCorrelationId=/ || /^CreationTime=/ || /^SubscriberNumber=/
这告诉 awk 如果记录与这三个正则表达式中的任何一个匹配,则打印该记录。一些注意事项:
在正则表达式中,
^
表示记录的开头。因此/^CreationTime=/
意味着以以下开头的记录CreationTime=
在 awk 中,像许多语言一样,
||
意味着逻辑或。^EventCorrelationId=/ || /^CreationTime=/
如果任一正则表达式匹配,则为true。
使用 sed
$ sed -En 's/.*(EventCorrelationId=[^ ]*).*(CreationTime=[^ ]*).*(SubscriberNumber=[^ ]*).*/\1\n\2\n\3/p' textfile
EventCorrelationId="615-493|-1899671563||1550927718000"
CreationTime="20190225094504"
SubscriberNumber=92705073362
在输出中使用备用分隔符
用作|
输出分隔符代替换行符:
$ sed -En 's/.*(EventCorrelationId=[^ ]*).*(CreationTime=[^ ]*).*(SubscriberNumber=[^ ]*).*/\1|\2|\3/p' textfile
EventCorrelationId="615-493|-1899671563||1550927718000"|CreationTime="20190225094504"|SubscriberNumber=92705073362
答案2
$ grep -Eo '(EventCorrelationId|CreationTime|SubscriberNumber)=[^ ]+' file
EventCorrelationId="615-493|-1899671563||1550927718000"
CreationTime="20190225094504"
SubscriberNumber=92705073362
grep -Eo
grep 在扩展正则表达式模式下(较少转义特殊字符)并仅打印匹配的部分(EventCorrelationId|CreationTime|SubscriberNumber)
匹配 EventCorrelationId 或 CreationTime 或 SubscriberNumber=[^ ]+
后跟“=”,后跟一次或多次非空格字符
编辑1:
现在用“|”分隔:
$ echo $(grep -Eo '(EventCorrelationId|CreationTime|SubscriberNumber)=[^ ]+' file) | tr ' ' '|'
EventCorrelationId="615-493|-1899671563||1550927718000"|CreationTime="20190225094504"|SubscriberNumber=92705073362
编辑2:
现在用“|”分隔以相反的顺序使用tac
:
$ echo $(grep -Eo '(EventCorrelationId|CreationTime|SubscriberNumber)=[^ ]+' file | tac) | tr ' ' '|'
SubscriberNumber=92705073362|CreationTime="20190225094504"|EventCorrelationId="615-493|-1899671563||1550927718000"
答案3
我尝试使用下面的 awk 方法,效果很好
j=`awk '{print NF}' filename `
for ((i=1;i<=$j;i++)); do awk -v i="$i" '$i ~ /EventCorrelationId/||$i ~ /CreationTime/||$i ~ /SubscriberNumber/{print $i}' filename ; done
输出
EventCorrelationId="615-493|-1899671563||1550927718000"
CreationTime="20190225094504"
SubscriberNumber=9270507336
答案4
您可以根据要输出的字段动态构建正则表达式来执行此练习:
$ perl -lne '
$re = join "|", map { +quotemeta } qw/EventCorrelationId CreationTime SubscriberNumber/;
print join "|", /(?:$re)=\H+/g;
' input.file
输出:
EventCorrelationId="615-493|-1899671563||1550927718000"|CreationTime="20190225094504"|SubscriberNumber=92705073362
在职的:
- 您想要输出的字段放置在匿名数组中
qw/.../
。 map { ... }
然后我们通过连接逻辑 OR来转换它们中的每一个|
。- 在最后一步中,我们应用刚刚在当前记录上构建的正则表达式 ,
$_
并通过管道符号连接捞出的字段|
以获取输出。