我有一个文件包含:
DEVICE="7" PGMNR="24" VCONF="800"
在此文件中,我想查找PGMNR="24"
并且需要不带"
.
可以PGMNR="24"
位于行中的任意位置。行的开头、中间或末尾。
我不知道如何获得该值。
来自评论的 XML 示例:
<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
<System
Dev="7"
PGMNR="24"
VCONF="800 800"
/>
<WA-NT
info="23 1 1 1 61 17 00"
name="Soja T#1"
/>
<WA-NT
info="23 2 2 1 61 17 00"
name="MatadorM"
/>
<SCALE
AdNr="0"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/>
<SCALE
AdNr="1"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/>
<SCALE
AdNr="2"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/>
<GSM
PIN=""
PORT="0"
TLF=""
/>
</NT3Config>
答案1
您可以grep
与 PCRE ( -P
) 一起使用:
grep -Po 'PGMNR=\"\K[^"]+(?=\")' file.txt
PGMNR=\"
将匹配该PGMNR="
部分,\K
将放弃匹配[^"]+
将包含号码零宽度正向先行模式
(?=\")
将确保数字后面跟着一个"
。
答案2
我已经使用解析器回答了这个问题 - 我认为这是“正确的方法”。
这将是“错误的方式”,但应该使用最少量的 POSIX 工具来解决这个问题:
grep PGMNR $filename | sed -e 's/.*PGMNR=\"//' -e 's/\".*//'
答案3
拜托——不要。 XML 不能很好地与正则表达式和基于行的解析配合使用,因为您可以在 XML 中执行许多语义相同但具有不同“模式匹配”的操作。
您xmlstarlet
可以提取一个xpath
表达式,为您提供价值。
或者我最喜欢的是使用 perl 来XML::Twig
解析 XML,然后再次以这种方式获取您想要的值。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> new ( 'pretty_print' => 'indented_a' ) -> parse ( \*DATA );
print "PGMNR: ", $twig -> get_xpath('//System',0) -> att('PGMNR'),"\n";
__DATA__
<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
<System Dev="7" PGMNR="24" VCONF="800 800" />
<WA-NT name="Soja T#1" info="23 1 1 1 61 17 00" />
<WA-NT name="MatadorM" info="23 2 2 1 61 17 00" />
<SCALE AdNr="0" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="1" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="2" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<GSM TLF="" PIN="" PORT="0" />
</NT3Config>
如果需要的话,这可以是“一行”,或者您也可以xmlstarlet
使用 XPATH。
perl -0777 -MXML::Twig -e 'print XML::Twig -> parse ( <> )-> get_xpath('//System',0) -> att('PGMNR');'
注意 - 我强烈反对基于正则表达式的解析的原因是因为这些都是呈现 XML 的完全有效的方式:
<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
<System
Dev="7"
PGMNR="24"
VCONF="800 800"
/>
<WA-NT
info="23 1 1 1 61 17 00"
name="Soja T#1"
/>
<WA-NT
info="23 2 2 1 61 17 00"
name="MatadorM"
/>
<SCALE
AdNr="0"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/>
<SCALE
AdNr="1"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/>
<SCALE
AdNr="2"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/>
<GSM
PIN=""
PORT="0"
TLF=""
/>
</NT3Config>
和这个:
<?xml version="1.0" encoding="utf-8"?>
<NT3Config
><System
Dev="7"
PGMNR="24"
VCONF="800 800"
/><WA-NT
info="23 1 1 1 61 17 00"
name="Soja T#1"
/><WA-NT
info="23 2 2 1 61 17 00"
name="MatadorM"
/><SCALE
AdNr="0"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/><SCALE
AdNr="1"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/><SCALE
AdNr="2"
Calib="0 0 0 0 0 0"
Setting="0 0 0 0 0 0 0"
/><GSM
PIN=""
PORT="0"
TLF=""
/></NT3Config>
和这个:
<?xml version="1.0" encoding="utf-8"?>
<NT3Config><System Dev="7" PGMNR="24" VCONF="800 800"/><WA-NT info="23 1 1 1 61 17 00" name="Soja T#1"/><WA-NT info="23 2 2 1 61 17 00" name="MatadorM"/><SCALE AdNr="0" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/><SCALE AdNr="1" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/><SCALE AdNr="2" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/><GSM PIN="" PORT="0" TLF=""/></NT3Config>
和这个:
<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
<System Dev="7" PGMNR="24" VCONF="800 800"/>
<WA-NT info="23 1 1 1 61 17 00" name="Soja T#1"/>
<WA-NT info="23 2 2 1 61 17 00" name="MatadorM"/>
<SCALE AdNr="0" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/>
<SCALE AdNr="1" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/>
<SCALE AdNr="2" Calib="0 0 0 0 0 0" Setting="0 0 0 0 0 0 0"/>
<GSM PIN="" PORT="0" TLF=""/>
</NT3Config>
您甚至可能会遇到上面的一些一元标签被显式关闭的情况:
<System Dev="7" PGMNR="24" VCONF="800 800"/>
和:
<System Dev="7" PGMNR="24" VCONF="800 800"></System>
就 XML 而言,两者说的是同一件事。
纯粹是因为锁定系统的额外约束,这是一种非常肮脏的方法 - 但请注意上面的警告 - 我们不再解析 XML,我们正在处理纯文本,而且它很容易被破坏。 (脆弱的代码会让您的系统管理员感到难过)。
#!/usr/bin/env perl
use strict;
use warnings;
local $/;
my ( $PGMNR ) = <DATA> =~ m/PGMNR=\"(\d+)\"/;
print $PGMNR;
__DATA__
<?xml version="1.0" encoding="utf-8"?>
<NT3Config>
<System Dev="7" PGMNR="24" VCONF="800 800" />
<WA-NT name="Soja T#1" info="23 1 1 1 61 17 00" />
<WA-NT name="MatadorM" info="23 2 2 1 61 17 00" />
<SCALE AdNr="0" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="1" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<SCALE AdNr="2" Setting="0 0 0 0 0 0 0" Calib="0 0 0 0 0 0" />
<GSM TLF="" PIN="" PORT="0" />
</NT3Config>
或者用 perl 编写 oneliner:
perl -0777 -e 'print <> =~ m/PGMNR=\"(\d+)\"/;'