Exclude delimiter with csplit

5

É possível remover o delimitador com csplit? Exemplo:

$ cat in
abc
---
def
---
ghi
$ csplit -q in /-/ '{*}'
$ ls x*
xx00  xx01  xx02
$ head xx*
==> xx00 <==
abc

==> xx01 <==
---
def

==> xx02 <==
---
ghi

Em vez do que ele fez, ou seja, dividir e manter o delimitador, ele pode ser solicitado a dividir e remover o delimitador?

Ou seja, o resultado desejado seria este:

$ sed -i '/-/d' xx*
$ head xx*
==> xx00 <==
abc

==> xx01 <==
def

==> xx02 <==
ghi

Embora isso possa ser feito em duas etapas, como acima, isso pode ser feito em uma única etapa?

Se isso não pode ser feito com csplit, existe uma maneira de uma etapa que é menor em comparação com as duas invocações (csplit + sed) acima? Nenhuma preferência para uma ferramenta usada desde que seja razoavelmente legível.

    
por levant pied 05.05.2016 / 21:33

3 respostas

2

Se você puder se contentar com uma correspondência de string em vez de uma correspondência de expressão regular

awk 'BEGIN {RS="---\n"; ORS=""} {print > sprintf("xx%02d", NR)}' in

Com o GNU awk (pelo menos na v4.0.1) é possível usar um regex para RS , por exemplo,

gawk 'BEGIN {RS="-+\n"; ORS=""} {print > sprintf("xx%02d", NR)}' in
    
por 05.05.2016 / 22:03
4

Como você parece estar usando gnu csplit , é bem simples:

csplit --suppress-matched infile /PATTERN/ '{*}'

i.e. use --suppress-matched para suprimir as linhas correspondentes a PATTERN .

Por sua nota, esta opção está disponível apenas com versões mais recentes de csplit ( coreutils ≥ 8.22)

    
por 05.05.2016 / 23:17
2
perl -ne 'BEGIN { $fnum=0; open $fh, ">", sprintf "xx%02d", $fnum++ } if (m/-/) { open $fh, ">", sprintf "xx%02d", $fnum++ } else { print $fh $_ }' inputfileorfileshere

Ou uma linha apropriada de reabrir para novo arquivo na correspondência apropriada usando awk ou o que for.

    
por 05.05.2016 / 21:55

Tags