Alessandro Solbiati
Alessandro Solbiati

Reputation: 979

Bash how to split file on empty line with awk

I have a text file (A.in) and I want to split it into multiple files. The split should occur everytime an empty line is found. The filenames should be progressive (A1.in, A2.in, ..)

I found this answer that suggests using awk, but I can't make it work with my desired naming convention

awk -v RS="" '{print $0 > $1".txt"}' file

I also found other answers telling me to use the command csplit -l but I can't make it match empty lines, I tried matching the pattern '' but I am not that familiar with regex and I get the following

bash-3.2$ csplit A.in ""
csplit: : unrecognised pattern

Input file:

A.in

4 
RURDDD

6
RRULDD
KKKKKK

26
RRRULU

Desired output:

A1.in

4 
RURDDD

A2.in

6
RRULDD
KKKKKK

A3.in

26
RRRULU

Upvotes: 3

Views: 3261

Answers (3)

downtheroad
downtheroad

Reputation: 419

Input file content:

$ cat A.in 
4 
RURDDD

6
RRULDD
KKKKKK

26
RRRULU

AWK file content:

BEGIN{
    n=1
}
{
    if(NF!=0){
        print $0 >> "A"n".in"
    }else{
        n++
    }
}

Execution:

awk -f ctrl.awk A.in

Output:

$ cat A1.in 
4 
RURDDD

$ cat A2.in 
6
RRULDD
KKKKKK

$ cat A3.in 
26
RRRULU

PS: One-liner execution without AWK file:

awk 'BEGIN{n=1}{if(NF!=0){print $0 >> "A"n".in"}else{n++}}' A.in

Upvotes: 0

kvantour
kvantour

Reputation: 26511

In any normal case, the following script should work:

awk 'BEGIN{RS=""}{ print > ("A" NR ".in") }' file

The reason why this might fail is most likely due to some CRLF terminations (See here and here).

As mentioned by James, making it a bit more robust as:

awk 'BEGIN{RS=""}{ f = "A" NR ".in"; print > f; close(f) }' file

If you want to use csplit, the following will do the trick:

csplit --suppress-matched  -f "A" -b "%0.2d.in" A.in '/^$/' '{*}'

See man csplit for understanding the above.

Upvotes: 2

James Brown
James Brown

Reputation: 37424

Another fix for the awk:

$ awk -v RS="" '{
    split(FILENAME,a,".")  # separate name and extension
    f=a[1] NR "." a[2]     # form the filename, use NR as number
    print > f              # output to file
    close(f)               # in case there are MANY to avoid running out f fds
}' A.in

Upvotes: 4

Related Questions