使用awk / sed读取列数

时间:2014-02-01 09:17:34

标签: bash sed awk

我有以下测试文件

Kmax Event File - Text Format
1 4 1000 
65 4121 9426 12312 
56 4118 8882 12307 
1273 4188 8217 12309 
1291 4204 8233 12308 
1329 4170 8225 12303 
1341 4135 8207 12306 
63 4108 8904 12300 
60 4106 8897 12307 
731 4108 8192 12306 
...
ÿÿÿÿÿÿÿÿ

在这个文件中,我想删除前两行并应用一些数学计算。例如,每列i将为$i-(i-1)*number。执行此操作的脚本如下

#!/bin/bash

if test $1 ; then
   if [ -f $1.evnt ] ; then
      rm -f $1.dat
      sed -n '2p' $1.evnt | (read v1 v2 v3
      for filename in $1*.evnt ; do
         echo -e "Processing file $filename"
         sed '$d' < $filename > $1_tmp
         sed -i '/Kmax/d' $1_tmp
         sed -i '/^'"$v1"' '"$v2"' /d' $1_tmp
         cat $1_tmp >> $1.dat
      done
      v3=`wc -l $1.dat | awk '{print $1}' `
      echo -e "$v1 $v2 $v3" > .$1.dat
      rm -f $1_tmp)
   else
      echo -e "\a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
      echo -e "  Event file $1.evnt doesn't exist  !!!!!!"
      echo -e "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
   fi   
else
   echo -e "\a!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
   echo -e "!!!!!  Give name for event files  !!!!!"
   echo -e "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
fi
awk '{print $1, $2-4096, $3-(2*4096), $4-(3*4096)}' $1.dat >$1_Processed.dat
rm -f $1.dat
exit 0

该文件不会总是有4列。有没有办法读取列数,打印这个数字并应用这些计算?

编辑我的想法是输入文件(* .evnt),将其转换为*.dat或任何其他ascii文件(实际上并不重要),只包括列中的数字然后应用计算$i=$i-(i-1)*number。此外,它将保留变量中的列数,这将在另一个程序中调用。例如,在上面的文件中,number=4096和示例输出文件是以下

65 25 1234 24
56 22 690 19
1273 92 25 21
1291 108 41 20
1329 74 33 15
1341 39 15 18
63 12 712 12
60 10 705 19
731 12 0 18

在控制台中我会收到消息There are 4 detectors

最后会产生一个新的file_processed.dat,其中file是awk输入文件的初始名称。

应该执行的方式如下

./myscript <filename>

其中<filename>是没有格式的名称。例如,文件的格式为filename.evnt,因此应使用

执行
./myscript filename

2 个答案:

答案 0 :(得分:3)

让我们从这开头看看它是否接近你想要做的事情:

$ numdet=$( awk -v num=4096 '
    NR>2 && NF>1 {
        out = FILENAME "_processed.dat"
        for (i=1;i<=NF;i++) {
            $i = $i-(i-1)*num
        }
        nf = NF
        print > out
    }
    END {
        printf "There are %d detectors\n", nf | "cat>&2"
        print nf
    }
    ' file )

There are 4 detectors

$ cat file_processed.dat
65 25 1234 24
56 22 690 19
1273 92 25 21
1291 108 41 20
1329 74 33 15
1341 39 15 18
63 12 712 12
60 10 705 19
731 12 0 18

$ echo "$numdet"
4
是吗?

答案 1 :(得分:1)

使用awk

awk 'NR<=2{next}{for (i=1;i<=NF;i++) $i=$i-(i-1)*4096}1' file