使用awk提取重叠的多行

时间:2014-02-13 15:20:52

标签: linux unix awk

我有一个看起来像这样的大文件(它实际上有12368行):

 Header
 175566717.000
 175570730.000
 175590376.000
 175591966.000
 175608932.000
 175612924.000
 175614836.000
 .
 .
 .
 175680016.000
 175689679.000
 175695803.000
 175696330.000

我想要做的是,删除标题,然后提取前2000行(第1行到第2000行),然后提取行1500到3500,然后提取3000到5000等等...... 我的意思是:提取一个2000行的窗口,在连续窗口之间重叠500行,直到文件末尾。

从上一篇文章中我得到了这个:

tail -n +2 myfile.txt | awk 'BEGIN{file=1} ++count && count==2000 {print > "window"file; file++; count=500} {print > "window"file}' 

但这不是我想要的。我没有500行重叠,我的第一个窗口有1999行而不是2000行。

任何帮助将不胜感激

3 个答案:

答案 0 :(得分:3)

 awk -v i=1 -v t=2000 -v d=500 'NR>1{a[NR-1]=$0}
END{while(i<NR-1){for(k=i;k<i+t;k++)print a[k] > i".txt"; close(i".txt");i=i+t-d}}' file

尝试以上行,您可以更改数字以适应您的新要求。你也可以定义自己的文件名。

t = 10(你的2000)和d = 5(你的500)的小测试

kent$  cat f
header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

kent$  awk -v i=1 -v t=10 -v d=5 'NR>1{a[NR-1]=$0}END{while(i<NR-1){for(k=i;k<i+t;k++)print a[k] > i".txt"; close(i".txt");i=i+t-d}}' f

kent$  head *.txt                                                                                                                      
==> 1.txt <==
1
2
3
4
5
6
7
8
9
10

==> 6.txt <==
6
7
8
9
10
11
12
13
14
15

==> 11.txt <==
11
12
13
14
15

答案 1 :(得分:0)

对此,awk并不理想。在Python中,您可以执行类似

的操作
with open("data") as fin:
    lines = fin.readlines()

    # remove header
    lines = lines[1:]

    # print the lines
    i = 0
    while True:
        print "\n starting window"
        if len(lines) < i+3000:
            # we're done.  whatever is left in the file will be ignored
            break
        for line in lines[i:i+3000]:
            print line[:-1] # remove \n

        i += 3000 - 500

答案 2 :(得分:0)

将整个文件读入内存通常不是一个好主意,在这种情况下没有必要。给定行号,您可以轻松计算应该进入的文件。例如:

awk '{
        a = int( NR / (t-d));
        b = int( (NR-t) / (t-d)) ;  
        for( f = b; f<=a; f++ ) {
            if( f >= 0 && (f * (t-d)) < NR  &&  ( NR <= f *(t-d) + t))
                print > ("window"(f+1))
        } 
    }' t=2000 d=500