简体   繁体   English

使用awk / sed读取列数

[英]Read the number of columns using awk/sed

I have the following test file 我有以下测试文件

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 
...
ÿÿÿÿÿÿÿÿ

In this file I want to delete the first two lines and apply some mathematical calculations. 在此文件中,我想删除前两行并应用一些数学计算。 For instance each column i will be $i-(i-1)*number . 例如,每列i将是$i-(i-1)*number A script that does this is the following 执行此操作的脚本如下

#!/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

The file won't always have 4 columns. 该文件并不总是具有4列。 Is there a way to read the number of columns, print this number and apply those calculations? 有没有办法读取列数,打印此列数并应用这些计算?

EDIT The idea is to have an input file (*.evnt), convert it to *.dat or any other ascii file(it doesn't matter really) which will only include the number in columns and then apply the calculation $i=$i-(i-1)*number . 编辑的想法是要有一个输入文件(* .evnt),将其转换为*.dat或任何其他ascii文件(这实际上并不重要),该文件仅包括列中的数字,然后应用计算$i=$i-(i-1)*number In addition it will keep the number of columns in a variable, that will be called in another program. 此外,它将列数保留在变量中,该变量将在另一个程序中调用。 For instance in the above file, number=4096 and a sample output file is the following 例如,在上面的文件中, 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

while in the console I will get the message There are 4 detectors . 在控制台中,我会收到消息, There are 4 detectors

Finally a new file_processed.dat will be produced, where file is the initial name of awk's input file. 最后,将生成一个新的file_processed.dat,其中file是awk输入文件的初始名称。

The way it should be executed is the following 它的执行方式如下

./myscript <filename>

where <filename> is the name without the format. 其中<filename>是不带格式的名称。 For instance, the files will have the format filename.evnt so it should be executed using 例如,文件的格式为filename.evnt因此应使用

./myscript filename

Let's start with this to see if it's close to what you're trying to do: 让我们从此开始,看看它是否与您要执行的操作接近:

$ 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

Is that it? 是吗

使用awk

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM