awk:基于另一个文件的输入在一个文件中进行模式替换

时间:2012-03-30 14:27:02

标签: awk

我有一个XML文件,其中包含一组这样的条目:

<attr name="trajectory" value="nodo2"/>

我想要做的是用“nodoX”形式的条目替换文件每个条目中的值字段,其中X应该从包含数字列表的第二个文件中读取,例如“file2”包含:

4
8
67
52

在这种情况下,我处理过的XML文件应该用以下代码替换前面的条目:

<attr name="trajectory" value="nodo4"/>
...
<attr name="trajectory" value="nodo8"/>
...
<attr name="trajectory" value="nodo67"/>
...
<attr name="trajectory" value="nodo52"/>
...

目前我正在尝试使用以下awk命令,但它无法正常工作:

awk '/"trajectory"/ {if (getline < "file2") {x=$1; sub(/"nodo2"/,"\"nodo"x"\"")}}1' $XML_INPUT_FILE > $XML_OUTPUT_FILE

有人可以建议在awk中完成此操作的正确方法吗?

由于

丹尼尔

4 个答案:

答案 0 :(得分:2)

getline < "file2"会覆盖$ 0,因此sub命令将无法执行您想要的操作。尝试:

awk '/"trajectory"/ {if (getline x < "file2") {sub(/"nodo2"/,"\"nodo"x"\"")}}1' 

请参阅http://www.gnu.org/software/gawk/manual/gawk.html#Getline

答案 1 :(得分:1)

嗯,你可以用awk ...

来做到这一点
awk 'BEGIN { c=1 ; while ((getline line < "OTHER_NUMBERS") > 0) { a[c]=line ; c++ } }
     NR == 1 { c=1 }
     /<attr name="trajectory" value="nodo[0-9]+".>/ {
          print gensub("^(.*=.nodo)[0-9]+(.*)","\\1" a[c] "\\2","g",$0)
          c++
     }
     ! /<attr name="trajectory" value="nodo[0-9]+".>/ { print }' XMLFILE

通常它会将您的数字文件读入索引数组,然后在每个(匹配的)trajectory行上打印替换。 注意如果数字文件中的行数少于nodo行的数量,则可能会使您失败...

答案 2 :(得分:0)

这可能对您有用:

 awk 'FNR==NR{n[++i]=$1;next};/"trajectory"/{sub(/[0-9]+/,n[++j],$3)}1' file2 XML

答案 3 :(得分:0)

下面的解决方案

awk '
BEGIN{i = 0; while(getline num < "file2"){a[i] = num;i++}}
/"trajectory"/{sub(/nodo2/,"node"a[NR-1], $0);print $0}' file1