ファイルを段落に分割し、各段落の識別子に基づいて結果フラグメントの名前を指定する方法

ファイルを段落に分割し、各段落の識別子に基づいて結果フラグメントの名前を指定する方法

3264880行を超える大容量ファイルがあります。このファイルを「BEGIN JOB」と「END JOB」という2つの文字列に基づいて分割して、複数のファイルに書きたいと思います。ファイル名は、2つの文字列とIdentifier行の間にあるいくつかの文字列に基づいている必要があります。BEGIN JOBEND JOB

サンプル

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

私のサンプルには2つしかないので、出力は2つのファイルになると予想されます。しかし、このような繰り返しパターンが1000個を超えています。

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

これを行うには、シェルスクリプトを作成することもできます。

答え1

GNU awkの使用

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

Perlを使用すると、CPANの便利なPath :: Tinyモジュールを使用できます。

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

答え2

このコマンドは、データの段落形式が同じ場合(たとえば、段落ごとに10行)、splitうまく機能します。分裂した人)。

#!/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

答え3

ファイル名を抽出するには、最初の「識別子」行を使用します。

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

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

空行をスキップし、実際の行をバッファに追加し、最初の(FN null)「識別子」が発生したときにファイル名を生成し、すべてを削除し、"バッファをEND JOB、リセットBUFおよびFN空の状態で印刷します。

関連情報