使用 awk 替换 html 文件

使用 awk 替换 html 文件

我的 awk 脚本从 读取记录file1,在 中找到相同的记录,file2并用其中定义的符号替换(记录的)替代位置。但很少有值没有按预期被替换。只有该单词的第一个实例被替换,例如

  • TYTYTY进入T##Y##
  • TYTYTYGGHG进入T##Y##GGHG
  • LEFT进入L##T
  • LEFT NAME进入L##T NAME

预期输出如下。

我的代码-

awk ' FNR==NR
{
if ($0 in word)
next
word[$0]=$0
for (i=1;i<=NF;i++)
 {
   old=$i
   new=""
   while (old) {
         len=length(old)
         new=new substr(old,1,1) substr("##",1,len-1)
         old=substr(old,4)
       }
      id=index(word[$0],$i)
      word[$0]=substr(word[$0],1,id-1) new substr(word[$0],id+length($i))
  }
 next
}

{
 for (i in word)
 {
  regex = "\\<" i "\\>"
  gsub(regex, ext[i])
  #id=index($0,i)
  #while(id>0) {
  #$0=substr($0,1,id-1) word[i] substr($0,id+length(word[i])) 
  #id=index($0,i)
 }
}
print 
}' records test.html > output.html
$ cat records

LEFT NAME
LEFT NAME 2
LEFT 
LEFT 123
TYTYTYGGHG
TYTYTY    
AB 8263
AB SCENARIO DEBUG
AB 8263 SCENARIO DEBUG

$ 猫测试.html

<html>
<body>
<hr><br><>span class="table">TabA</span><table>
<tr class="column">
 <td>LEFT NAME</td>
 <td>LEFT</td>
 <td></td>
 <td>LEFT NAME 2</td>
 <td>LEFT 123</td>
 <td>TYTYTYGGHG</td>
 <td></td>
 <td>TYTYTY</td>
</tr>
<tr class="data">
<td></td>
<td></td>
<td></td>
<td>AB 8263</td>
<td></td>
<td></td>
<td>AB SCENARIO DEBUG</td>
<td>AB 8263 SCENARIO DEBUG</td>
</tr>
</table>
</body>
</html>

所需的操作 -

<html>
<body>
<hr><br><>span class="table">TabA</span><table>
<tr class="column">
 <td>L##T N##E</td>
 <td>L##T</td>
 <td></td>
 <td>L##T N##E 2</td>
 <td>L##T 1##</td>
 <td>T##Y##G##G</td>
 <td></td>
 <td>T##Y##</td>
</tr>
<tr class="data">
<td></td>
<td></td>
<td></td>
<td>A# 8##3</td>
<td></td>
<td></td>
<td>A# S##N##I# D##U#</td>
<td>A# 8##3 S##N##I# D##U#</td>
</tr>
</table>
</body>
</html>

电流输出-

<html>
<body>
<hr><br><>span class="table">TabA</span><table>
<tr class="column">
 <td>L##T NAME</td>
 <td>L##T</td>
 <td></td>
 <td>L##T NAME 2</td>
 <td>L##T 123</td>
 <td>T##Y##GGHG</td>
 <td></td>
 <td>T##Y##</td>
</tr>
<tr class="data">
<td></td>
<td></td>
<td></td>
<td>A# 8##3</td>
<td></td>
<td></td>
<td>A# S##N##I# D##U#</td>
<td>A# 8##3 SCENARIO DEBUG</td>
</tr>
</table>
</body>
</html>

答案1

我很惊讶这不是一个骗局,不过https://stackoverflow.com/questions/34375020/why-the-output-of-array-using-awk-is-not-in-right-order非常接近。

总括:awk 数组没有排序(一般来说)

当您使用 awk 中的数组进行迭代时,for (i in word)返回“索引”值(也称为下标或键)的顺序是未指定经过标准;传统上,这些数组被实现为哈希表,并按照该哈希表的顺序进行迭代,该哈希表是某个哈希码对某个值取模,在发生冲突时可能会被修改或重新哈希(所谓的“封闭哈希”)。这与插入条目/键的顺序不同,通常它是确定性的,但足够复杂,从人类的角度来看似乎是随机的。

因此,在您的示例中,根据您使用的 awk 和您的确切数据,循环很有可能在处理之前for处理条目;结果,包含匹配的行被更改为,随后当循环尝试不匹配时,该行不会进一步更改。同样,不匹配的先处理,不匹配的先处理。在不同的 awk 上运行或使用不同的 file1 数据运行很可能会产生不同的顺序,从而产生不同的结果;在不同的环境中运行可能会这样做。LEFTLEFT NAMELEFT NAMELEFTL##T NAMELEFT NAMETYTYTYTYTYTYGGHGAB 8263AB 8263 SCENARIO DEBUG

同样在您的FNR==NR(即 file1)分支中,new-new substr(old,1,1) substr("##",1,len-1)需要=不是-.就我个人而言,我发现制作该子循环更自然

    old=$i; new=""; for(c=1; c<=length(old); c++) new = new (c%3==1? substr(old,c,1): "#")

虽然差异很小。尽管您应该知道您的子循环,但如果 file1 中的任何单词完全由一个或多个0数字组成,可选地在+或之前,-并且可选地后跟e和 任何数字,会将其更改为空字符串,而不是相同长度的屏蔽版本。

相关内容