Question: I have a data gethered in one file organised in blocks

```
---- BLOCK ONE ----
some data
another data
more data
more data
-------------------

---- BLOCK two ----
some data
another data
-------------------

---- BLOCK THREE ----
some data
another data
more data
-------------------

```

and so one. togethere around 2000 blocks.

I need to extract those blocks which have less then 4 entries (data lines).
Any idea how to do it (perl prefered ; )

Answer: 
```perl
$ perl -00 -F'\n' -n -e '
  $file = shift @F;
  pop @F;
  if (@F < 4) {
    $file =~ s/^---- | ----//g;
    open(OUT, ">", $file.".txt");
    print OUT join("\n", @F), "\n"
  }' input.txt

```

This perl one-liner uses `-00` to read the input in paragraph mode (separated by two-or-more newlines), `-F` to auto-split the input on newlines into array @F, and `-n` to auto-read the input without printing it (similar to `sed -n`).

First it uses shift to get the first element of @F into variable $file. Then pop @F to discard the last element (`-------------------`). If there are less than 4 elements remaining, then: remove the `----`  and  `----` from $file, open "$file.txt" for write, and print the remainder of the array to that file.

If you don't like those filenames, you can use some other method - e.g. increment a counter variable, something like `$file = sprintf "file%04i.txt", ++$counter` inside the `if` block instead of using the `s///` operator.

BTW, if you want to keep the `---- BLOCK...` header and the `------*` footer then replace the `shift` and `pop` lines with `$file = $F[0]` and change the `if` test to `if (@F < 6)`.

Sample output (using `tail` so that it prints the filenames):

```
$ tail BLOCK*.txt
==> BLOCK THREE.txt <==
some data
another data
more data

==> BLOCK two.txt <==
some data
another data

```

---

Same thing as a standalone script, but using a counter to generate the filename:

```perl
$ cat split-blocks.pl
#!/usr/bin/perl

use strict;
my $counter;

$/='';

while(<<>>) {
  my @lines = split /\n/;
  my $file = shift @lines;
  pop @lines;

  if (@lines < 4) {
    $file = sprintf 'file%04i.txt', ++$counter
    open(OUT, ">", $file) || die "couldn't open $file for write: $!\n";
    print OUT join("\n", @lines), "\n"
  }
};

$ ./split-blocks.pl input.txt

$ tail file*
==> file0001.txt <==
some data
another data

==> file0002.txt <==
some data
another data
more data

```
```perl
perl -lne '
    if (/^-+$/) {
        print join "\n", @M, $_ if $#M < 4;
        @M = ();
        next;
    }

    if (/^-/) {
        $M[0] = $_;
        next;
    }

    push @M, $_ if $#M >= 0;
' file

```

Read the file with `perl` line by line thanks to `perl` auto-printing option disabled `(-n)`.

Then if we are inside a section `(push @M, $_ if $#M >= 0)` push the line inside an array.

If we are inside the ending secion `(/^-+$/)` and the array length is less then 4 then print it and empty the array `(@M = ())`.

Otherways we begin a section `(/^-/)` and so save the current line as the first value in the array, and os it becomes the header.

---

I have deleted the empty lines but you can kept it if desire.