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

```
Using any `awk`:

```
awk 'NF && !/^-/{ buf= buf (data?ORS:"") $0; data++ }
          /^-+$/{ if(data<4) { print (ors?ORS:"") buf; ors=ORS }; buf=data="" }' infile

```

Output:

```none
some data
another data

some data
another data
more data

```

If you wanted to keep the blocks header/footer:

```
awk 'NF{ buf= buf (data?ORS:"") $0; data++ }
 /^-+$/{ if(data<=5) { print (ors?ORS:"") buf; ors=ORS }; buf=data="" }' infile

```

Output:

```none
---- BLOCK two ----
some data
another data
-------------------

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

```