Como dividir um arquivo em parágrafos e nomear as partes resultantes com base em um identificador presente em cada parágrafo

0

Eu tenho um arquivo grande com mais de 3264880 linhas. Eu queria dividir esse arquivo com base em duas cadeias "BEGIN JOB" e "END JOB" e escrevê-lo em vários arquivos e o nome do arquivo deve ser baseado em um determinado Identifier que está presente entre as linhas BEGIN JOB e END JOB

Dados de amostra

BEGIN JOB
  Identifier "ADHOC_Extract"
   DateModified "2018-10-02"
   TimeModified "15.09.52"
   BEGIN DSRECORD
      Identifier "ROOT"
      OLEType "CJobDefn"
      Readonly "0"
      Name "ADHOC_Extract"
END JOB

BEGIN JOB
  Identifier "HOC_Extract"
   DateModified "2018-11-02"
   TimeModified "12.09.52"
   BEGIN DSRECORD
      Identifier "ROOT"
      OLEType "CJobDefn"
      Readonly "0"
      Name "HOC_Extract"
END JOB

Saída esperada como dois arquivos, uma vez que minha amostra tem apenas dois ... Mas ela terá mais de 1.000 desses padrões repetidos

ADHOC_Extract.txt

BEGIN JOB
  Identifier "ADHOC_Extract"
   DateModified "2018-10-02"
   TimeModified "15.09.52"
   BEGIN DSRECORD
      Identifier "ROOT"
      OLEType "CJobDefn"
      Readonly "0"
      Name "ADHOC_Extract"
END JOB

 HOC_Extract.txt

BEGIN JOB
  Identifier "HOC_Extract"
   DateModified "2018-11-02"
   TimeModified "12.09.52"
   BEGIN DSRECORD
      Identifier "ROOT"
      OLEType "CJobDefn"
      Readonly "0"
      Name "HOC_Extract"
END JOB

Eu estou bem mesmo para escrever um script de shell para o mesmo

    
por sirish 12.10.2018 / 20:43

3 respostas

4

Com o GNU awk

gawk -v RS="" '
    match($0, /Identifier "([^"]+)/, m) {
        print > (m[1]".txt")
        close(m[1]".txt")
    }
' sample.txt

Com Perl, usando o módulo Path :: Tiny de conveniência do CPAN

perl -MPath::Tiny -00 -ne '/Identifier "(.+?)"/ and path("$1.txt")->spew($_)' sample.txt 
    
por 12.10.2018 / 21:44
0

Se os parágrafos nos dados tiverem o mesmo formato (isto é, dez linhas por parágrafo), o comando split será muito eficaz ( dividir homem ).

#!/bin/bash   
#remove blank lines from the original dataset.

awk NF original_data.txt > Free_spaces_data.txt 

# split the dataset into files (paragraph per file), each paragraph is 10 lines.

split -l 10 Free_spaces_data.txt new 

 #rename the files based on the internal name within each paragraph

for f in ./new*?; do
name=$(cat $f | awk -F'"' '/Name/{print $2}')
  mv "${f}" "${name}.txt"; 
done
    
por 12.10.2018 / 21:29
0

Isso levará a primeira linha "Identifier" para extrair o nome do arquivo:

awk '
!/^ *$/         {BUF = BUF RS $0
                }

! FN  &&
/Identifier/    {FN = $NF ".txt"
                 gsub (/"/, "", FN)
                }
/END JOB/       {print BUF > FN
                 BUF = FN = ""
                }
' file

Salta linhas vazias, acrescenta a linha real a um buffer, cria um nome de arquivo na primeira ocorrência ("FN vazia") "Identificador", removendo qualquer " e imprime o buffer em END JOB , redefinindo BUF e FN para esvaziar.

    
por 13.10.2018 / 00:15