如何在UNIX中提取关键字后面的文本
我有一个文本文件(如何在UNIX中提取关键字后面的文本,unix,text,awk,sed,text-extraction,Unix,Text,Awk,Sed,Text Extraction,我有一个文本文件(file.txt),其中包含我从外部源收到的结果墙(没有换行符、空格等)。从这个文件中,我需要找到所有提到的单词serId,然后打印出它后面的字母数字序列。字母数字序列的长度不限,但以字符,结尾。如何提取这些字母数字序列 我曾尝试使用sed/awk查找脚本/代码,但结果似乎围绕着要查找的已知序列,而不是未知序列 例如,我想从以下示例文本中提取28655784-EE: {"preRollbackCheckResults":[],"patchingHistory":[{"backu
file.txt
),其中包含我从外部源收到的结果墙(没有换行符、空格等)。从这个文件中,我需要找到所有提到的单词serId
,然后打印出它后面的字母数字序列。字母数字序列的长度不限,但以字符,
结尾。如何提取这些字母数字序列
我曾尝试使用sed/awk查找脚本/代码,但结果似乎围绕着要查找的已知序列,而不是未知序列
例如,我想从以下示例文本中提取28655784-EE
:
{"preRollbackCheckResults":[],"patchingHistory":[{"backupStatus":"Available","rollbackStatus":"Available","additionalNote":"Patching CDS as planned","appliedBy":"xxrbsgCDS02services","appliedDate":"2019-01-18T12:45:33.926+0000","totalTime":"29 min, 47 sec","serId":"28655784-EE","patchDescription":"DB 18.4.0.0.0 Oct 2018 PSU
请尝试此awk脚本(仅限于gawk):
如果您需要终止,
awk -F '","' 'match($0,/serId\":\"[^,]*/,m){print m[1]","}' input.txt
说明:
-F“,”
将文件解析为由,
awk -F '","' 'match($0,/serId\":\"[^,]*/,m){print m[1]","}' input.txt
match($0,“serId[^,]*”,m)
在当前记录中筛选,匹配以serId开头的字符串
以,
结尾的字符串。将结果放入数组m
print substr(m[0],8)
从第8个位置打印匹配的字符串grep-o
是一个非常简单的解决方案:
我创建了一个文件,其中包含以下行:
serId12345
serIdABCde123;
Ser_idblabla;
第一行不以分号结尾,第三行以错误的单词开头,因此只有第二行是正确的
我启动了以下命令:grep-o“serId[0-9a-zA-Z]*;”testtttt.txt
,结果如下:
serIdABCde123;
根据您在评论中发布的简短示例,我有两个建议:
- 如果文件格式正确,请尝试了解其结构和用途
- 如果格式不正确并且只能解释为一堆文本,请使用以下Perl:
试运行:perl -lne '@m=/"serId":"([^"]+)"/g; print "@m"' file.txt
$ cat file.txt {"preRollbackCheckResults":[],"patchingHistory":[{"backupStatus":"Available","rollbackStatus":"Available","additionalNote":"Patching CDS as planned","appliedBy":"xxrbsgCDS02services","appliedDate":"2019-01-18T12:45:33.926+0000","totalTime":"29 min, 47 sec","serId":"28655784-EE","patchDescription":"DB 18.4.0.0.0 Oct 2018 PSU{"preRollbackCheckResults":[],"patchingHistory":[{"backupStatus":"Available","rollbackStatus":"Available","additionalNote":"Patching CDS as planned","appliedBy":"xxrbsgCDS02services","appliedDate":"2019-01-18T12:45:33.926+0000","totalTime":"29 min, 47 sec","serId":"28655784-EE","patchDescription":"DB 18.4.0.0.0 Oct 2018 PSU $ perl -lne '@m=/"serId":"([^"]+)"/g; print "@m"' file.txt 28655784-EE 28655784-EE
使用任何sed:
$ sed 's/.*"serId":"\([^"]*\).*/\1/' file
28655784-EE
提供示例输入文件。对于未知序列,使用正则表达式匹配。ask是一个工具。我正在使用Grep2.20,它似乎支持-o选项。txt文件中的一个示例是t{“preRollbackCheckResults”:[],“patchingHistory”:[{“backupStatus”:“Available”,“rollbackStatus”:“Available”,“additionalNote”:“Patching CD as Planning”,“appliedBy”:“xxrbsgCDS02services”,“appliedDate”:“2019-01-18T12:45:33.926+0000”,“totalTime”:“29分钟47秒”,“serId”:“28655784-EE”,“Patching Description”:“DB18.4.0.0.0 2018年10月PSU…所以我要做的是在文件中找到“serId”,然后提取“28655784-EE”我不确定,但这看起来像是一个
json
文件,你看过jq
了吗?你的问题是要显示简洁的、可测试的样本输入和预期的输出,这样我们才能帮助你。正确的解决方案不是像你在当前grep和awk答案下的评论中所说的那样,将grep+awk结合起来。这很有效当我将你的解决方案与Dudi Boy的相结合时。非常感谢。当我将你的解决方案与Dominique的相结合时,这很有效。非常感谢。我这样做了,但追加投票不会持续。我不知道为什么?啊。“声誉低于15的人的投票会被记录,但不会改变公开显示的帖子分数。”但是我已经投了赞成票。第二个要匹配的参数()是一个regexp,而不是一个字符串,所以你应该使用regexp/
而不是字符串“
分隔符,即match($0,/serId):“[^,]*/,…)
而不是match($0,“serId\”:\“[^,]*,…)
[^,]*
应该是[^]*
但是,对第三个arg to match()使用gawk的全部目的是将regexp段隔离为捕获组,以便在操作块中引用,因此代码应该是match($0,/serId):“([^”]*)/,m){print m[1]}
否则,使用任何awk都可以编写match($0,/serId):“[^”]*/{print substr($0,RSTART+8,RLENGTH-8)}
感谢@Ed Morton,更新了建议。