我正在尝试提取由Java程序生成的文件名的名称。这个Java程序吐出多行,我确切地知道文件名的格式是什么。 Java程序吐出的信息文本如下:
ABCASJASLEKJASDFALDSF
Generated file YANNANI-0008876_17.xml.
TDSFALSFJLSDJF;
我正在捕获变量中的输出,然后以下列格式应用sed运算符:
sed -n 's/.*\(YANNANI.\([[:digit:]]\).\([xml]\)*\)/\1/p'
结果集是:
YANNANI-0008876_17.xml.
但是,我的问题是想要提取文件名以停止在.xml
。永远不应该提取最后一个点。
有没有办法用sed做到这一点?
让我们来看看你的捕获组实际捕获的内容:
$ grep 'YANNANI.\([[:digit:]]\).\([xml]\)*' infile
Generated file YANNANI-0008876_17.xml.
那可能不是你想要的:
\([[:digit:]]\)
只捕获一个数字(并且它周围的捕获组没有做任何事情)\([xml]\)*
是“任何x
,m
或l
,0次或更多次”,所以它匹配空字符串(如上所述 - 或者根本不匹配!),x
,xx
,lll
,mxxxxxmmmmlxlxmxlmxlm
,xml
,. ..更有意义的是:
[[:digit:]_]*
.xml
,字面意思(逃离时期):\.xml
.*
,确保匹配其余部分(在本例中为句点)所以你要提取的字符串的正则表达式变成了
$ grep 'YANNANI.[[:digit:]_]*\.xml' infile
Generated file YANNANI-0008876_17.xml.
并使用sed删除行上的所有其他内容,我们用.*\( ... \).*
包围正则表达式:
$ sed -n 's/.*\(YANNANI.[[:digit:]_]*\.xml\).*/\1/p' infile
YANNANI-0008876_17.xml
这假设你真的是在.
(任何角色)之后的YANNANI
。
你可以调用sed两次:首先是打印然后是替换模式:
sed -n 's/.*\(YANNANI.\([[:digit:]]\).\([xml]\)*\)/\1/p' | sed 's/\.$//g'
最后一个sed将删除你的第一个sed提取的所有行末尾的所有最后一个.
或者您可以根据需要选择awk
解决方案:
awk '/.*YANNANI.[0-9]+.[0-9]+.xml/{print substr($NF,1,length($NF)-1)}'
这将打印与你的正则表达式匹配的所有行的最后一个字段(并使用substr
截断它的最后一个字符)。