キーワード境界を使用してファイルを分割する方法

キーワード境界を使用してファイルを分割する方法

多くのvcardを含むvcfファイルがあります。

vcfファイルをOutlookにインポートすると、最初のvcardのみがインポートされたようです。

だから私はそれらを分離したい。

vcardが次から始まるという点を考えると

BEGIN:VCARD

そして

END:VCARD

各vcardを独自のファイルに分割する最善の方法は何ですか?

ありがとう

修正する

皆様のご回答ありがとうございます。これらの性格の質問と同様に、猫の皮をむく方法はいくつかあります。だからこれを選択しました。

集める

以下は、それぞれの回答で私が好きなものと他の答えの1つを選択した理由の概要です。

  • csplit:私はこのアプローチの単純さが本当に好きです。ファイル拡張子も設定できたらと思います。
  • gawk:私が要求したすべてのことを行います。
  • paralell:働いた。しかし、新しいものをインストールする必要があります。 (また、私のホームディレクトリに新しい/ binディレクトリを作成することにしました)
  • perl:連絡先の名前に基づいてvcfを生成するのが好きです。しかし、-oオプションは実際には機能しません。

結論として

  • それで一番最初に去ったのはperl少し古いからだった。
  • 次はparalell何かを新しくインストールする必要があります。
  • これは、csplit私が知っている限り、出力ファイルに拡張子を作成できないためです。
  • すぐに使えるユーティリティで、ファイル名を少し変更できるほど汎用性があるため、賞はバカに戻ります。追加ポイントもありますcmp:)

答え1

awkを使用してこれを行うことができます。

$ curl -O https://raw.githubusercontent.com/qtproject/qt-mobility\
/d7f10927176b8c3603efaaceb721b00af5e8605b/demos/qmlcontacts/contents/\
example.vcf

$ gawk ' /BEGIN:VCARD/ { close(fn); ++a; fn=sprintf("card_%02d.vcf", a); 
        print "Writing: ", fn } { print $0 > fn; } ' example.vcf
Writing:  card_01.vcf
Writing:  card_02.vcf
Writing:  card_03.vcf
Writing:  card_04.vcf
Writing:  card_05.vcf
Writing:  card_06.vcf
Writing:  card_07.vcf
Writing:  card_08.vcf
Writing:  card_09.vcf

$ cat card_0* > all.vcf
$ cmp example.vcf all.vcf
$ echo $?
0

詳細

awkラインは次のように動作します。aこれは各行ごとに増加するカウンタでありBEGIN:VCARD、sprintfは出力ファイル名(に格納されているfn)を設定するために使用されます。各行に対して、現在の行($0)が現在のファイル(名前fn)に追加されます。

最終echo $?表示はcmp成功です。つまり、リンクされた個々のファイルは、元のサンプルvcfサンプルと同じです。

awkの出力リダイレクトは、シェルの出力リダイレクトとは異なります。これは> fn、awkが最初にファイルがすでに開いていることを確認することを意味します。すでに開いている場合は awkそれに加える。それ以外の場合は開いて切ります。

これらのリダイレクトロジックのために、明示的に閉じる必要があります。暗黙的に開くファイル。そうしないと、入力ファイルに多数のレコードが含まれている場合、呼び出しはファイルを開く制限に達します。

答え2

csplit -f vcard input.txt -z '/END:VCARD/+1' '{*}'

答え3

csplitのGnuバージョンは拡張子を設定できます。 Ignacioの答えは私の考えでは最もきれいです。拡張子を取得するには、「printf」形式を使用して最後に一度だけ調整します。

csplit -f vcard -b %02d.vcard input.txt -z '/END:VCARD/+1' '{*}'

以下はGNUのマニュアルページの関連スニペットですcsplit

   -b, --suffix-format=FORMAT
          use sprintf FORMAT instead of %02d

答え4

このスクリプトを使用して操作を実行できます。知られているvcfファイルの分割

使用例

$ split_vcf.pl 

Error! Input VCF filename missing,  -i

Usage: perl split_vcf.pl -i input_file -o output_dir [OPTION]

    -v,         Verbosity levels, 1-3

スクリプトを実行します。

mkdir vcf_files
split_vcf.pl  -i current.vcf -o vcf_files

関連情報