如何在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,更新了建议。