我试图提取由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做到这一点?
答案 0 :(得分:0)
让我们看看您的捕获组实际捕获的内容:
$ 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
。
答案 1 :(得分:0)
您可以调用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
截断它的最后一个字符)。