awk获取多个文件中的字段

时间:2016-01-02 13:02:24

标签: bash awk

我有来自ns2的移动文件,我想在不同的文件中以不同的间隔提取节点坐标。 更清楚的是,如果我的文件看起来像这样

cat mob.tcl
$node_(0) set X_ 656.02
$node_(0) set Y_ 1819.19
$node_(0) set Z_ 0
$ns_ at 0.0 "$node_(0) setdest 656.02 1819.19 0.00"
$ns_ at 1.0 "$node_(0) setdest 654.99 1818.19 1.44"
$node_(1) set X_ 365.41
$node_(1) set Y_ 1284.31
$node_(1) set Z_ 0
$ns_ at 1.0 "$node_(1) setdest 365.41 1284.31 0.00"
$ns_ at 2.0 "$node_(0) setdest 652.74 1816.04 3.12"
$ns_ at 2.0 "$node_(1) setdest 365.7 1281.79 2.54"
$ns_ at 3.0 "$node_(0) setdest 649.08 1812.52 5.08"
$ns_ at 3.0 "$node_(1) setdest 366.2 1277.44 4.37"
$ns_ at 4.0 "$node_(0) setdest 643.59 1807.23 7.62"
$ns_ at 4.0 "$node_(1) setdest 366.88 1271.47 6.01"
$ns_ at 5.0 "$node_(0) setdest 636.46 1800.37 9.90"
$ns_ at 5.0 "$node_(1) setdest 367.78 1263.63 7.90"

我想拥有的是5个文件time_1,time_2 ... time_5,每个文件都有节点id,x坐标和y坐标,例如time_1将有

1 365.41 1284.31 
到目前为止我设法做的是用这样的awk获取字段

cat mob.tcl | awk -F'[_ ()]' '{print $4 "\t" $7 "\t" $10 "\t" $11}'

但是

  1. 我想根据行开头的内容

    分隔提取的字段

    如果我尝试

    cat mob.tcl | awk '/$ns_/' -F'[_ ()]' '{print $4 "\t" $7 "\t" $10 "\t" $11}'
    

    只处理以$ ns_开头的行,我收到错误

  2. 我想根据$ 4的值将这些字段放在不同的文件中,所以它应该是for循环但是我不知道应该怎么写它(我不知道什么是正确的语法AWK。

  3. 我到目前为止写的是

     cat testAwk | awk '
     BEGIN { FS="[_() ]"}
     {
     if ($1 == "$node") 
        {
           print $3 "\t" $8 ;
        } else if ($1 == "$ns") {
           print  $7 "\t" $10 "\t" $11 ;
           time=5;
           for (i = 1; i <= time; i++)
           {   if ($4==i)
               {print  $7 "\t" $10 "\t" $11 >> "Time"$i}
           }
       } 
    
     }
    

    但文件“时间”$ i未正确创建

2 个答案:

答案 0 :(得分:1)

如果您希望输出到命名文件,这应该可以解决问题:

$ awk -v OFS='\t' '$1 == "$ns_" && $3 > 0 {
    time=$3
    split($4, node, /[()]/)
    print node[2], $6, $7 >> "Time" int(time)
}' file
$ for f in Time*; do echo $f; cat $f; done
Time1
0       654.99  1818.19
1       365.41  1284.31
Time2
0       652.74  1816.04
1       365.7   1281.79
Time3
0       649.08  1812.52
1       366.2   1277.44
Time4
0       643.59  1807.23
1       366.88  1271.47
Time5
0       636.46  1800.37
1       367.78  1263.63

请注意,循环已被删除,因为它会在每一行上造成不必要的迭代。

由于上述问题是关于打印到命名文件,因此该代码(与问题的示例代码不同)不会向stdout打印任何重复的行。

最后,cat is not needed使用awk命令。

答案 1 :(得分:0)

TXR解决方案:

@(repeat)
@  (cases)
$node_(@node) set X_ @x
$node_(@node) set Y_ @y
@  (or)
$ns_ at @nil "$node_(@node) setdest @x @y @nil
@  (end)
@  (output `Time@node` :append)
@node @x @y
@  (end)
@(end)

注意:这会导致来自$node$ns条目的一些重复数据。没有必要处理$node条目。

执行命令

$ rm Time*
$ txr node-xyz.txr data
$ ls Time*
Time0  Time1
$ cat Time0
0 656.02 1819.19
0 656.02 1819.19
0 654.99 1818.19
0 652.74 1816.04
0 649.08 1812.52
0 643.59 1807.23
0 636.46 1800.37
$ cat Time1
1 365.41 1284.31
1 365.41 1284.31
1 365.7 1281.79
1 366.2 1277.44
1 366.88 1271.47
1 367.78 1263.63

要仅处理$ns素材,我们可以删除@(cases)块:

@(repeat)
$ns_ at @nil "$node_(@node) setdest @x @y @nil
@  (output `Time@node` :append)
@node @x @y
@  (end)
@(end)