如何通过使用关键字边界分割文件


15

我有一个vcf文件,其中包含许多vcard。

将vcf文件导入Outlook时,似乎仅导入第一个vcard。

因此,我想将它们分开。

假设vcard以

BEGIN:VCARD

并以

END:VCARD

将每个vcard拆分成自己的文件的最佳方法是什么。

谢谢

更新

感谢您的所有回复。与这种性质的问题一样,有多种方法可以为猫皮。这就是为什么我选择自己选择的理由。

围捕

这是我对每个答案的喜好以及促使我选择其中一个的摘要。

  • csplit:我真的很喜欢这种方法的简洁性。我只是希望它能够设置文件扩展名。
  • gawk:它满足了我的所有要求。
  • paralell:工作。但是我必须安装新东西。(它还决定在我的主目录中创建一个新的/ bin目录)
  • perl:我喜欢它根据联系人的姓名创建了vcf。但是-o选项并没有真正起作用

结论

  • 所以第一个要去的是perl因为它有点破
  • 接下来是paralell因为我必须安装新东西
  • 接下来是csplit,因为据我所知,它无法在输出文件上创建扩展名
  • 因此,该奖项颁给了gawk,因为它是一个易于使用的实用程序,而且用途广泛,足以让我可以稍微修改一下文件名。也有奖金标记cmp:)

您尝试使用-b吗?
伊格纳西奥·巴斯克斯

Answers:


11

您可以使用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中的输出重定向与shell中的输出重定向不同。这意味着使用> fnawk首先检查文件是否已经打开。如果已经打开,则awk会附加到它。如果不是,则打开并截断它。

由于这种重定向逻辑,我们必须显式关闭隐式打开的文件,因为否则在输入文件包含许多记录的情况下,调用将达到打开文件的限制。


您需要关闭文件以避免awk中太多打开文件错误。stackoverflow.com/questions/32878146/… 因此命令变为:gawk'/ BEGIN:VCARD / {close(fn); ++ a; fn = sprintf(“ card_%02d.vcf”,a); 打印“ Writing:”,fn} {打印$ 0 >> fn; }'example.vcf
Dan Bennett

@DanBennett非常感谢您的提示!我已经更新了答案,还简化了重定向逻辑/固定重定向相关的说明。
maxschlepzig


5

Gsp版本的csplit可以设置扩展名-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

我使用的是Mac,花了一些时间才想出要使用gcsplit,但是一旦这样做,这个答案就对我有所帮助。
卢克·吉迪恩

4

您可以使用此脚本来完成这项工作。它称为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

split_vcf.pl是Windows版本。对于UNIX,请修改在文件名中添加“ \”的子make_filename。
J Dan

4

使用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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.