使用 "awk" 解析文本并使用 "sed" 修改其中一列
Parse Text with "awk" and Modify One Of The Columns With "sed"
我有一个用竖线“|”分隔的数据我想用 awk 解析它并将其写入数据库。
EndpointRequest|ID-ip-172-31-70-119-eu-west-1-compute-internal-209879772|2022-05-12 08:20:03:467|0|ip-172-31-70-119|616e50193233020648|vfgh|GenericAmount|61d458303574b21f|Display|v1|Display-v1|PrepaidEndpoint|6227300ec1786d26|Corporate|62273041c8cf901071786d81|Health Line||||69.28.67.153|Java/1.8.0_321|application/xml|468|475|POST||http://127.0.0.1/endpoint/||200||2022-05-12 08:20:03:458|0|468|7|0|0|0|true|Http|null|null|HTTPConnector:CallPrepaid|Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\nAuthorization: Bearer e3edbb1d8f5d8c828dc584ed293602bf\nContent-Type: application/xml\nX-Amzn-Trace-Id: Root=1-627cc333-7167\nX-Forwarded-For: XX.XX.XX.XX\nX-Forwarded-Port: 443\nX-Forwarded-Proto: https\n\n<?xml version="1.0"?>\n<!DOCTYPE cp_request SYSTEM "cp_req_websvr.dtd">\n<cp_request>\n <cp_id>YY1880</cp_id>\n <cp_transaction_id>SDP</cp_transaction_id>\n <op_transaction_id>arr684754251</op_transaction_id>\n <application>1</application>\n <action>2</action>\n <user_id type="MSISDN">9999999999</user_id>\n <cp_timer>5</cp_timer>\n <transaction_price>1900</transaction_price>\n <transaction_currency>0</transaction_currency>\n</cp_request>
数据有很多行,就像上面的一样,我使用下面的命令来获取某些字段。
more file.log | egrep "EndpointRequest|EndpointSuccess|EndpointFailure" | egrep "PrepaidEndpoint" | awk -F"|" '{print "|""|""|""|""|""|""|""|""|""|""|""|""|""|""|"}'
这里的问题是,在最后一个字段 (#44) 上,有一个包含一些 headers 和 XML 有效负载的 HTTP 响应。我需要获取“op_transaction_id”值(“arr684754251”)并将其添加到 awk 命令的末尾,但我无法这样做。在单独的命令中,我可以通过“sed”获取该值,
sed -n "s/.*<op_transaction_id>\(.*\)<\/op_transaction_id>.*//p" file.log
如何将“sed”命令迁移到“awk”命令中,这样我就可以将“op_transaction_id”值作为“awk”中的字段之一。
预期输出:
EndpointRequest|ID-ip-172-31-70-119-eu-west-1-compute-internal-209879772|2022-05-12 08:20:03:467|0|ip-172-31-70-119|Display-v1|PrepaidEndpoint|Corporate|Health Line|69.28.67.153|475|200||2022-05-12 08:20:03:458|0|arr684754251
谢谢 bash 大师。感谢任何帮助。
How do I migrate the "sed" command into the "awk" command
您可以利用 gensub
function,考虑下面的简单示例,让 file.txt
被 |
剪切成 3 列:
<tag>text1</tag>|A|1
<tag>text2</tag>|B|2
<tag>text3</tag>|C|3
并说你想从第一个字段中获取标签内的内容并使用 ,
那么你可能会这样做
awk 'BEGIN{FS="|";OFS=","}{=gensub(/<tag>(.+)<\/tag>/,"\1",1,);print}' file.txt
给出输出
text1,A,1
text2,B,2
text3,C,3
gensub
的参数是正则表达式、替换、如何(指向要替换的数字或 "g"
全部)和目标。 gensub
执行 return 更改的字符串,然后我们将其分配为第一个字段的新值。 FS
通知字段分隔符是 |
和 OFS
输出字段分隔符是 ,
。请注意,您必须 而不是 盲目地从 sed
复制您的正则表达式以成为 gensub
的第一个参数。例如 (
和 )
在 GNU sed
中用于表示文字括号并且需要转义以获得捕获组,在 GNU AWK
(
和 )
表示捕获组,必须进行转义以获得文字括号。
(在 gawk 4.2.1 中测试)
我有一个用竖线“|”分隔的数据我想用 awk 解析它并将其写入数据库。
EndpointRequest|ID-ip-172-31-70-119-eu-west-1-compute-internal-209879772|2022-05-12 08:20:03:467|0|ip-172-31-70-119|616e50193233020648|vfgh|GenericAmount|61d458303574b21f|Display|v1|Display-v1|PrepaidEndpoint|6227300ec1786d26|Corporate|62273041c8cf901071786d81|Health Line||||69.28.67.153|Java/1.8.0_321|application/xml|468|475|POST||http://127.0.0.1/endpoint/||200||2022-05-12 08:20:03:458|0|468|7|0|0|0|true|Http|null|null|HTTPConnector:CallPrepaid|Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2\nAuthorization: Bearer e3edbb1d8f5d8c828dc584ed293602bf\nContent-Type: application/xml\nX-Amzn-Trace-Id: Root=1-627cc333-7167\nX-Forwarded-For: XX.XX.XX.XX\nX-Forwarded-Port: 443\nX-Forwarded-Proto: https\n\n<?xml version="1.0"?>\n<!DOCTYPE cp_request SYSTEM "cp_req_websvr.dtd">\n<cp_request>\n <cp_id>YY1880</cp_id>\n <cp_transaction_id>SDP</cp_transaction_id>\n <op_transaction_id>arr684754251</op_transaction_id>\n <application>1</application>\n <action>2</action>\n <user_id type="MSISDN">9999999999</user_id>\n <cp_timer>5</cp_timer>\n <transaction_price>1900</transaction_price>\n <transaction_currency>0</transaction_currency>\n</cp_request>
数据有很多行,就像上面的一样,我使用下面的命令来获取某些字段。
more file.log | egrep "EndpointRequest|EndpointSuccess|EndpointFailure" | egrep "PrepaidEndpoint" | awk -F"|" '{print "|""|""|""|""|""|""|""|""|""|""|""|""|""|""|"}'
这里的问题是,在最后一个字段 (#44) 上,有一个包含一些 headers 和 XML 有效负载的 HTTP 响应。我需要获取“op_transaction_id”值(“arr684754251”)并将其添加到 awk 命令的末尾,但我无法这样做。在单独的命令中,我可以通过“sed”获取该值,
sed -n "s/.*<op_transaction_id>\(.*\)<\/op_transaction_id>.*//p" file.log
如何将“sed”命令迁移到“awk”命令中,这样我就可以将“op_transaction_id”值作为“awk”中的字段之一。
预期输出:
EndpointRequest|ID-ip-172-31-70-119-eu-west-1-compute-internal-209879772|2022-05-12 08:20:03:467|0|ip-172-31-70-119|Display-v1|PrepaidEndpoint|Corporate|Health Line|69.28.67.153|475|200||2022-05-12 08:20:03:458|0|arr684754251
谢谢 bash 大师。感谢任何帮助。
How do I migrate the "sed" command into the "awk" command
您可以利用 gensub
function,考虑下面的简单示例,让 file.txt
被 |
剪切成 3 列:
<tag>text1</tag>|A|1
<tag>text2</tag>|B|2
<tag>text3</tag>|C|3
并说你想从第一个字段中获取标签内的内容并使用 ,
那么你可能会这样做
awk 'BEGIN{FS="|";OFS=","}{=gensub(/<tag>(.+)<\/tag>/,"\1",1,);print}' file.txt
给出输出
text1,A,1
text2,B,2
text3,C,3
gensub
的参数是正则表达式、替换、如何(指向要替换的数字或 "g"
全部)和目标。 gensub
执行 return 更改的字符串,然后我们将其分配为第一个字段的新值。 FS
通知字段分隔符是 |
和 OFS
输出字段分隔符是 ,
。请注意,您必须 而不是 盲目地从 sed
复制您的正则表达式以成为 gensub
的第一个参数。例如 (
和 )
在 GNU sed
中用于表示文字括号并且需要转义以获得捕获组,在 GNU AWK
(
和 )
表示捕获组,必须进行转义以获得文字括号。
(在 gawk 4.2.1 中测试)