Awk 提取html标记';属性

Awk 提取html标记';属性,awk,Awk,我正在寻找使用awk解析此HTML片段的最简单方法: <a id=1 data1="sth11" data2="sth12" data3="sth13 "><div class="cl1"></div></a> ; <a id=2 data1="sth21" data2="sth22" data3=" sth23&

我正在寻找使用awk解析此HTML片段的最简单方法:

<a id=1 data1="sth11" data2="sth12" data3="sth13 "><div class="cl1"></div></a> ;
<a id=2 data1="sth21" data2="sth22" data3=" sth23"><div class="cl2"></div></a>   ;
<a id=2 data1="sth31" data3="  sth33  " data2="sth32" ><div class="cl3"></div></a>  ;
我试图浏览awk的指南,但它似乎太大了,虽然这似乎是一个简单的问题,我仍然没有找到完美的解决方案尚未

如果我需要其他东西或类似的东西来避免每次询问,最好有解决方案、解释和一些来源

我试过一个简单的方法,但这个不好,因为字段是固定的,因此没有连接
并且不修剪空格:

cat数据| awk-F'”/data3=/{print$6}'


谢谢大家

正如其他人所建议的那样,专用html/xml解析器将是最好的解决方案,但如果您不能使用,您可以尝试以下GNU awk解决方案:

awk -F '[ >]' '{ gsub("data3=\"[[:space:]]+","data3=\"",$0);gsub("[[:space:]]+\"","\"",$0);for (i=1;i<=NF;i++) { if ($i ~ /data3/) { split($i,map,"=");gsub("\"","",map[2]);printf "%s;",map[2] } } }' file
awk-F'[>]''{gsub(“data3=\”[[:space:]+”,“data3=\”,$0);gsub([:space:]+\”,“\”,$0);for(i=1;i)
gsub(“data3=\”[[:space:]+,“data3=\”,$0);#删除data3元素定义中的任何空格
gsub(“[:space:]+\”、“\”、$0);

对于(i=1;i,正如其他人所建议的,专用html/xml解析器将是最好的解决方案,但如果您不能使用,可以尝试以下GNU awk解决方案:

awk -F '[ >]' '{ gsub("data3=\"[[:space:]]+","data3=\"",$0);gsub("[[:space:]]+\"","\"",$0);for (i=1;i<=NF;i++) { if ($i ~ /data3/) { split($i,map,"=");gsub("\"","",map[2]);printf "%s;",map[2] } } }' file
awk-F'[>]''{gsub(“data3=\”[[:space:]+”,“data3=\”,$0);gsub([:space:]+\”,“\”,$0);for(i=1;i)
gsub(“data3=\”[[:space:]+,“data3=\”,$0);#删除data3元素定义中的任何空格
gsub(“[:space:]+\”、“\”、$0);

首先,我强烈建议不要使用(i=1;i)进行XML处理

对于您提供的示例,此命令可能会产生所需的输出:

awk -F 'data3="|>' 'BEGIN{ORS=";"}{sub(/^ +/,"",$2); sub(/[ "].*/,"",$2); print $2}' file
输出:

sth13;sth23;sth33;

演示:

首先,我强烈建议不要使用XML处理。有更好的工具

对于您提供的示例,此命令可能会产生所需的输出:

awk -F 'data3="|>' 'BEGIN{ORS=";"}{sub(/^ +/,"",$2); sub(/[ "].*/,"",$2); print $2}' file
输出:

sth13;sth23;sth33;

演示:

$grep-oP'(?
$grep-oP'(?如果列号不固定(只是注意到oP的输入在最后一行切换了data2/data3):

$awk-v ORS=';''匹配($0,/data3=“[^”]+”/){
m=substr($0,RSTART+7,RLENGTH-8);
gsub(/^++$/,“”,m);print m}'ip.txt
sth13;sth23;sth33;
  • -v ORS=';”
    将输出记录分隔符更改为
    ,而不是换行符
  • match($0,/data3=“[^”]+”/)
    将匹配包含
    data3=“
    后跟非
    字符和
    字符的行
  • m=substr($0,RSTART+7,RLENGTH-8)
    将提取匹配部分减去
    data3=“
    和最后一个
    字符
  • gsub(/^++$/,“”,m)
    将从
    m

修改F.Knorr的解决方案:

awk -F '[ >]' '{ gsub("data3=\"[[:space:]]+","data3=\"",$0);gsub("[[:space:]]+\"","\"",$0);for (i=1;i<=NF;i++) { if ($i ~ /data3/) { split($i,map,"=");gsub("\"","",map[2]);printf "%s;",map[2] } } }' file
awk-F'data3=“*”-v ORS=”;“'NF>1{sub(/*”*/,“,”,$2);打印$2}”
  • -F'data3=“*”
    将使用
    data3=“
    后跟可选空格作为字段分隔符
  • NF>1
    将确保仅选择包含
    data3=“
    的行
  • sub(/*“*/,”,$2)
    将从行中删除可选空格和剩余字符
对于多个匹配:


awk-F'data3=“*”-v ORS=”;“{for(i=2;i如果列号不固定(注意OP的输入在最后一行切换了data2/data3):

$awk-v ORS=';''匹配($0,/data3=“[^”]+”/){
m=substr($0,RSTART+7,RLENGTH-8);
gsub(/^++$/,“”,m);print m}'ip.txt
sth13;sth23;sth33;
  • -v ORS=';”
    将输出记录分隔符更改为
    ,而不是换行符
  • match($0,/data3=“[^”]+”/)
    将匹配包含
    data3=“
    后跟非
    字符和
    字符的行
  • m=substr($0,RSTART+7,RLENGTH-8)
    将提取匹配部分减去
    data3=“
    和最后一个
    字符
  • gsub(/^++$/,“”,m)
    将从
    m

修改F.Knorr的解决方案:

awk -F '[ >]' '{ gsub("data3=\"[[:space:]]+","data3=\"",$0);gsub("[[:space:]]+\"","\"",$0);for (i=1;i<=NF;i++) { if ($i ~ /data3/) { split($i,map,"=");gsub("\"","",map[2]);printf "%s;",map[2] } } }' file
awk-F'data3=“*”-v ORS=”;“'NF>1{sub(/*”*/,“,”,$2);打印$2}”
  • -F'data3=“*”
    将使用
    data3=“
    后跟可选空格作为字段分隔符
  • NF>1
    将确保仅选择包含
    data3=“
    的行
  • sub(/*“*/,”,$2)
    将从行中删除可选空格和剩余字符
对于多个匹配:


awk-F'data3=“*”-v ORS=”;“{for(i=2;我到目前为止你试过什么?
awk
就像数字42。有学习
awk
的资源。不过,我建议使用
xmlstarlet
xpath
dasel
等工具来解决这个问题……谢谢你,由于平台的限制,我不得不坚持使用awk。到目前为止你试过什么?
awk
就像数字42。有学习
awk
的资源。不过,我建议使用
xmlstarlet
xpath
dasel
等工具来解决这个问题……谢谢你,由于平台的限制,我不得不坚持使用awk。你可以使用
grep-oP'data3=“\h*\K.*(?=\h*))“
为了避免
sed
@Sundeep,thx,标准lookback不支持可变长度断言。尝试避免
perl
细节。否则,只需使用
perl
即可。您可以使用
grep-oP'data3=“\h*\K.*(?=\h*)”“
为了避免
sed
@Sundeep,thx,标准lookback不支持可变长度断言。尝试避免
perl
细节。否则,只需使用
perl