0

I have a file like this:

    1         2         3         4         5
 0.05775  0.00238  0.02514   0.00469  0.01882
 0.26868  0.04114  0.09359  0.02155  0.01367
 0.11413  0.00907  0.04032  0.02487   0.01156
 0.03759  0.00624  0.00819  0.01527   0.01128
 0.09910  0.03416  0.02280  0.00627   0.00433
    6         7         8         9        10
0.01798   0.00035   0.00672  0.02180  0.00184
0.01880  0.00834   0.04975  0.05503   0.00234
0.00242  0.00618   0.04936  0.02320   0.00269
 0.00931  0.00611   0.02371  0.00299   0.00353
 0.00763  0.00197  0.00673  0.00338   0.00182
   11        12        13        14        15
 0.00330   0.00521   0.00495   0.00426   0.00403
0.01121   0.02891   0.02162   0.02235   0.01534
0.01081   0.01871   0.00888   0.01835   0.00867
0.00684   0.00965   0.00645   0.00802   0.00317
0.00671   0.00333   0.00376  0.00204   0.00028

This example contains three main blocks of information. The first row of each block contains always an integer number, while the others rows contains decimal numbers. I want to take the first 4 rows of each block.

Output:

    1         2         3         4         5
 0.05775  0.00238  0.02514   0.00469  0.01882
 0.26868  0.04114  0.09359  0.02155  0.01367
 0.11413  0.00907  0.04032  0.02487   0.01156
    6         7         8         9        10
0.01798   0.00035   0.00672  0.02180  0.00184
0.01880  0.00834   0.04975  0.05503   0.00234
0.00242  0.00618   0.04936  0.02320   0.00269
   11        12        13        14        15
 0.00330   0.00521   0.00495   0.00426   0.00403
0.01121   0.02891   0.02162   0.02235   0.01534
0.01081   0.01871   0.00888   0.01835   0.00867

I was trying to do something with sed but, with no sucess.

  • Do all blocks have one header line and exactly five lines of data? Or do some rows have variable amounts? – Wildcard Feb 23 '18 at 20:24
  • Hi @Wildcard. All blocks has a header line and N lines of data (here, I post 5 lines as an example ). But always the N lines is constant. – alloppp Feb 23 '18 at 20:33
  • And, do all blocks have at least three lines after the header? – Wildcard Feb 23 '18 at 20:39
  • yes! at least three lines. – alloppp Feb 23 '18 at 20:43
2

I asked:

Do all blocks have one header line and exactly five lines of data? Or do some rows have variable amounts?

If it's exactly 6 lines per block, you can use:

sed -n 'N;N;N;p;N;N' file.txt

But if not, then use:

sed -n '/\./!{N;N;N;p;}' file.txt

The latter command, on encountering a line without any periods, will print that and the following three lines (without checking them for periods). It will then skip the following lines until another is encountered that doesn't have periods.


If you can, I recommend fixing the tool that's providing this data so it gives it in a more sensible format.

  • Great @Wildcard. What happen if I need to print many lines (30 for example) after a line without period. Does it possible to do something like sed -n '/\./!{30 lines;p;}' file.txt – alloppp Feb 23 '18 at 20:41
  • sed '/\./!{N;N;N;p};d' infile. for 30 put 30 N or with awk: awk -v 'a=30' '!/\./{print;for(i=1;i<=a;i++){getline;print}}' infile – ctac_ Feb 23 '18 at 21:07
  • OK, your solution with awk is what I was trying to found. Thanks @ctac_ – alloppp Feb 23 '18 at 21:10
0
$ awk -v RS='\n  ' '{
   count=split($0,lines,/\n/);
   lines[1]="  "lines[1];
   max=4 ; if (count < max) { max = count };
   for (i=1; i <= max; i++) print lines[i];
  }' input 
     1         2         3         4         5
0.05775  0.00238  0.02514   0.00469  0.01882
0.26868  0.04114  0.09359  0.02155  0.01367
0.11413  0.00907  0.04032  0.02487   0.01156
    6         7         8         9        10
0.01798   0.00035   0.00672  0.02180  0.00184
0.01880  0.00834   0.04975  0.05503   0.00234
0.00242  0.00618   0.04936  0.02320   0.00269
   11        12        13        14        15
0.00330   0.00521   0.00495   0.00426   0.00403
0.01121   0.02891   0.02162   0.02235   0.01534
0.01081   0.01871   0.00888   0.01835   0.00867

This awk script make use of the fact that the header lines for each block start with at least two spaces, while the data lines don't. If we set the record separator (RS) to a newline followed by two spaces, we can process each block individually.

Each block is then split into into individual lines. The first line has two space characters pre-pended (to replace the spaces eaten up by the record separator), and then the first 4 lines are printed (or less, if there happens to be less than 4 lines in a block).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.