Extraction de plusieurs lignes avec recouvrement à l’aide de awk

J’ai un gros fichier qui ressemble à ceci (il a en fait 12368 lignes):

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

Ce que je veux faire, c’est supprimer l’en-tête, puis extraire les 2000 premières lignes (ligne 1 à 2000), puis extraire les lignes 1500 à 3500, puis 3000 à 5000 et ainsi de suite … Ce que je veux dire, c’est: extraire une fenêtre de 2000 lignes avec un chevauchement de 500 lignes entre les fenêtres contiguës jusqu’à la fin du fichier.

Depuis un post précédent, j’ai eu ceci:

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

Mais ce n’est pas ce que je veux. Je n’ai pas les 500 lignes qui se chevauchent et ma première fenêtre a 1999 lignes au lieu de 2000.

Toute aide serait appréciée

  awk -vi=1 -vt=2000 -vd=500 'NR>1{a[NR-1]=$0} END{while(i i".txt"; close(i".txt");i=i+td}}' file 

essayez ci-dessus ligne, vous pouvez changer les numéros pour répondre à votre nouvelle exigence. Vous pouvez également définir vos propres noms de fichiers.

petit test avec t = 10 (votre 2000) et d = 5 (votre 500)

 kent$ cat f header 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 kent$ awk -vi=1 -vt=10 -vd=5 'NR>1{a[NR-1]=$0}END{while(i i".txt"; close(i".txt");i=i+td}}' 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 

awk n’est pas idéal pour cela. En Python, vous pouvez faire quelque chose comme

 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 

Lire la totalité du fichier en mémoire n’est généralement pas une bonne idée et, dans ce cas, n’est pas nécessaire. Étant donné un numéro de ligne, vous pouvez facilement calculer les fichiers dans lesquels il doit aller. Par exemple:

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