web-dev-qa-db-ja.com

一貫性のないテキストファイルからCSVを作成する

(ほとんど)空白行で区切られた3行または4行のテキストで構成されるファイルに、大まかに構造化されたレコードがあります。すべてのレコードに空白行セパレーターがあるわけではありませんが、各レコードの最後の行は「追加」という単語で始まります。 1行の各レコードの前に行番号が付いたcsvファイルを作成したいと思います。これまでのところ、任意の数のスペースと冗長コンマで区切られたすべてのレコードの連結を作成することしかできませんでした。

論理的に私は次を達成しようとしています:

行が「追加」で始まる場合、行を読む
それ以外の場合は、「newline」を「、」に置き換えます
または行が空白の場合は削除します
endif

サンプルデータ:

Peter Green  
Space Monkey at Area 51  
Joined  
Added by SF 3 weeks ago  
Will Rossiter  
Joined  
Added by SF 3 weeks ago

Dean Matthews  
Guitarist at Blues  
Joined  
Added by SF 3 weeks ago  
Hobbit Mak  
Farnborough, United Kingdom  
Joined  
Added by SF 3 weeks ago  

Keneth W Moorfield  
THE STOREMAN  
Joined  
Added by SF 3 weeks ago  
Mick Georgious  
Software Engineer  
Joined  
Added by SF 3 weeks ago
4
SeniorMoments

試してください:

_awk '/./{ printf "%s%s", $0, (/Added/?"\n":",") }' data
_

サンプル入力データの使用:

_$ awk '/./{printf "%s%s",$0,(/Added/?"\n":",")}' data
Peter Green,Space Monkey at Area 51,Joined,Added by SF 3 weeks ago
Will Rossiter,Joined,Added by SF 3 weeks ago
Dean Matthews,Guitarist at Blues,Joined,Added by SF 3 weeks ago
Hobbit Mak,Farnborough, United Kingdom,Joined,Added by SF 3 weeks ago
Keneth W Moorfield,THE STOREMAN,Joined,Added by SF 3 weeks ago
Mick Georgious,Software Engineer,Joined,Added by SF 3 weeks ago
_

使い方:

  • _/./{...}_

    これは、行に文字が含まれている場合にのみ、中括弧でコマンドを実行します。つまり、空白行は無視されます。

  • printf "%s%s",$0,(/Added/?"\n":",")

    これにより、_$0_で示される行が出力されます。その後に、行が正規表現Addedと一致するかどうかに応じて、コンマまたは改行が続きます。

5
John1024

可能なsedソリューション(awkで行番号付けを行う):

$ sed -n -e :a -e '$!{/^$/!N}; /,Added/ {P;D}; s/\n/,/; ta' data | awk '{print NR","$0}'
1,Peter Green,Space Monkey at Area 51,Joined,Added by SF 3 weeks ago
2,Will Rossiter,Joined,Added by SF 3 weeks ago
3,Dean Matthews,Guitarist at Blues,Joined,Added by SF 3 weeks ago
4,Hobbit Mak,Farnborough, United Kingdom,Joined,Added by SF 3 weeks ago
5,Keneth W Moorfield,THE STOREMAN,Joined,Added by SF 3 weeks ago
6,Mick Georgious,Software Engineer,Joined,Added by SF 3 weeks ago 

基本的に、空でない入力行を追加し、改行をコンマに置き換えますが、各反復でレコード全体があるかどうかを確認し、ある場合はそれを吐き出します。

  • プログラムラベルを設定:a
  • ファイルの最後にない場合$!その後、空でない行をパターンスペースに追加します{/^$/!N}
  • レコードの最後にある場合/,Added/、それを印刷しますP、パターンスペースからDを削除します
  • 改行s/,/\n/をコンマに置き換え、成功するとaに分岐して戻る
3
steeldriver

FWIW、これはPerlオプションです:

$ Perl -lne '
    Push @rec, $_ unless /^$/; if (/^Added/) {print join ",", ++$n, @rec; undef @rec;}
' data
1,Peter Green,Space Monkey at Area 51,Joined,Added by SF 3 weeks ago
2,Will Rossiter,Joined,Added by SF 3 weeks ago
3,Dean Matthews,Guitarist at Blues,Joined,Added by SF 3 weeks ago
4,Hobbit Mak,Farnborough, United Kingdom,Joined,Added by SF 3 weeks ago
5,Keneth W Moorfield,THE STOREMAN,Joined,Added by SF 3 weeks ago
6,Mick Georgious,Software Engineer,Joined,Added by SF 3 weeks ago 
2
steeldriver