How to use for loop to extract data from text file and store it to a new file?

Viewed 179

I have text data in following format:

Generated by trjconv : P/L=1/400 t=   0.00000
11214
    1P1     aP1    1  80.48  35.36   4.25
    2P1     aP1    2  37.45   3.92   3.96
    3P2     aP2    3  18.53  -9.69   4.68
    4P2     aP2    4  55.39  74.34   4.60
Generated by trjconv : P/L=2/400 t=   0.00000
11214
    1P1     aP1    1  80.48  35.36   4.25
    2P1     aP1    2  37.45   3.92   3.96
    3P2     aP2    3  18.53  -9.69   4.68
    4P2     aP2    4  55.39  74.34   4.60
Generated by trjconv : P/L=3/400 t=   0.00000
11214
    1P1     aP1    1  80.48  35.36   4.25
    2P1     aP1    2  37.45   3.92   3.96
    3P2     aP2    3  18.53  -9.69   4.68
    4P2     aP2    4  55.39  74.34   4.60
.
.
.

I'm using the sed command to extract the selected lines

sed -n '3~6p' filename > output_file1

The data has around a million lines and one frame of data has around 11217 lines. I want to extract these lines and store it to the new file. With this command I have to do that 11217 times. Can someone show how to use to for loop with sed command? Output should look like this,

output1.txt
1P1     aP1    1  80.48  35.36   4.25
1P1     aP1    1  80.48  35.36   4.25
1P1     aP1    1  80.48  35.36   4.25
output2.txt
 2P1     aP1    2  37.45   3.92   3.96
 2P1     aP1    2  37.45   3.92   3.96
 2P1     aP1    2  37.45   3.92   3.96
output3.txt
3P2     aP2    3  18.53  -9.69   4.68
3P2     aP2    3  18.53  -9.69   4.68
3P2     aP2    3  18.53  -9.69   4.68
.
.
.
output11217.txt
11217P11217  aP11217 11217 18.53  -9.69   4.68
...
.
.
.
2 Answers

Using a loop for that would be an anti-pattern, just do this:

$ cat tst.sh
#!/usr/bin/env bash

awk -v OFS='\t' 'sub(/^ +/,""){print $1, NR, $0}' "${@:--}" |
sort -k1,1 -k2,2n |
cut -f3- |
awk '
    $1 != prev {
        close(out)
        out = "output" (++c) ".txt"
        prev = $1
    }
    { print > out }
'

$ ./tst.sh file

$ head output*
==> output1.txt <==
1P1     aP1    1  80.48  35.36   4.25
1P1     aP1    1  80.48  35.36   4.25
1P1     aP1    1  80.48  35.36   4.25

==> output2.txt <==
2P1     aP1    2  37.45   3.92   3.96
2P1     aP1    2  37.45   3.92   3.96
2P1     aP1    2  37.45   3.92   3.96

==> output3.txt <==
3P2     aP2    3  18.53  -9.69   4.68
3P2     aP2    3  18.53  -9.69   4.68
3P2     aP2    3  18.53  -9.69   4.68

==> output4.txt <==
4P2     aP2    4  55.39  74.34   4.60
4P2     aP2    4  55.39  74.34   4.60
4P2     aP2    4  55.39  74.34   4.60

If you're not sure what the above is doing just execute each of the commands in order, adding the next command to the pipeline in each step.

This might work for you (GNU utils):

sed '/^\s/!d;s/^\s*//' file |
sort -ns |
uniq -w 8 --group |
csplit -qf output -b %d.txt --suppress - '/^$/' '{*}'

Filter file removing unwanted lines and spaces.

Sort numerically using a stable sort to preserve duplicates position.

Separate groups of lines by a space line.

Split files on space lines.

N.B. Output files are named from 0 not 1.

Related