web-dev-qa-db-ja.com

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

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

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

したがって、それらを分割したいと思います。

Vcardが

BEGIN:VCARD

そしてで終わる

END:VCARD

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

ありがとう

[〜#〜]更新[〜#〜]

すべての応答をありがとう。この性質の質問と同様に、猫の皮をむくにはさまざまな方法があります。これが私が選択した理由です。

ラウンドアップ

以下は、私が各回答から気に入った点と、そのうちの1つを選択したきっかけのまとめです。

  • csplit:この方法の簡潔さが本当に気に入りました。私はそれがファイル拡張子も設定できることを望みました。
  • gawk:私が求めたすべてのことを行いました。
  • paralell:動作しました。しかし、新しいものをインストールする必要がありました。 (また、私のホームディレクトリに新しい/ binディレクトリを作成することにしました)
  • Perl:連絡先の名前に基づいてvcfを作成するのが好きでした。しかし、-oオプションは実際には機能しませんでした

結論

  • 最初に行ったのはPerlでした
  • 次はparalellでした。新しいものをインストールする必要があったからです。
  • 次はcsplitでした。これは、私が見る限り、出力ファイルに拡張子を作成できないためです。
  • そのため、賞はgawkに贈られます。これは、すぐに利用できるユーティリティであり、ファイル名を少し変更して変更できるほど用途が広いためです。 cmpのボーナスマークも:)
15
denormalizer

ジョブには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行は次のように機能します:aBEGIN:VCARD行ごとに増分されるカウンターであり、同時に出力ファイル名はsprintf(fnに格納)を使用して構築されます。各行について、現在の行($0)が現在のファイル(fnという名前)に追加されます。

最後のecho $?は、cmpが成功したことを意味します。つまり、連結されたすべての単一ファイルは元のvcfの例と同じです。

Awkの出力リダイレクトは、Shellとは動作が異なることに注意してください。つまり、> fnを指定すると、awkはまずファイルがすでに開いているかどうかを確認します。それがすでに開いている場合は、awk appends to it です。そうでない場合は、開いて切り捨てます。

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

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

CsplitのGnuバージョンは拡張機能を設定できます-イグナシオの答えは最も簡潔だと思います。拡張機能を取得するには、最後の微調整が必​​要です-'printf'形式を使用します。

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

以下は、gnu csplit manページからの関連スニペットです。

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

このスクリプトを使用して、ジョブを実行できます。 split-vcf-file と呼ばれます。

使用例

$ 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
4
slm

GNU Parallelを使用すると、次のことができます。

cat foo.vcf | parallel --pipe -N1 --recstart BEGIN:VCARD 'cat >{#}'

または、反論できる http://oletange.blogspot.com/2013/10/useless-use-of-cat.html 代わりにこれを使用できます。

< foo.vcf parallel --pipe -N1 --recstart BEGIN:VCARD 'cat >{#}'

その他の例を見る: http://www.gnu.org/software/parallel/man.html

紹介ビデオを見る: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

インストール10秒:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh
4
Ole Tange