Anahtar kelime sınırlarını kullanarak dosya bölme


15

Çok sayıda vcards içeren bir vcf dosyam var.

Outlook'a vcf dosyasını içe aktarırken yalnızca ilk vcard'ı içeriyor gibi görünüyor.

Bu yüzden onları ayırmak istiyorum.

Bir vcard'ın

BEGIN:VCARD

ile biter

END:VCARD

Her vcard'ı kendi dosyasına bölmenin en iyi yolu nedir?

Teşekkürler

GÜNCELLEME

Tüm yanıtlar için teşekkürler. Bu doğadaki sorularda olduğu gibi, bir kediyi ciltlemek için çeşitli yollar vardır. İşte yaptığımı seçmemin nedeni.

HESABI YUVARLAMAK

Her cevaptan neyi sevdiğimi ve bunlardan birini seçmemi sağlayan şeylerden oluşan bir özet.

  • csplit: Bu yöntemin özlü olmasını gerçekten çok sevdim. Sadece dosya uzantısını da ayarlayabilmeyi diledim.
  • gawk: Sorduğum her şeyi yaptı.
  • paralell: Çalıştı. Ama yeni şeyler yüklemem gerekiyordu. (ayrıca ev dizinimde yeni bir / bin dizini yapmaya karar verdi)
  • perl: Kişinin adına göre vcf oluşturmasını sevdim. Ancak -o seçeneği gerçekten işe yaramadı

Sonuç

  • İlk gidilecek şey perlbiraz kırılmış olmasıydı.
  • Sonra paralellyeni şeyler yüklemem gerekti
  • Sırada csplit, çünkü görebildiğim kadarıyla çıktı dosyalarında uzantı oluşturamıyor
  • Böylece ödül gawk'ye, hazır bir yardımcı program olduğu için ve dosya adını biraz kesip değiştirebileceğim kadar çok yönlüdür. Bonus işaretleri cmpde :)

Kullanmayı denedin -bmi?
Ignacio Vazquez-Abrams

Yanıtlar:


11

İş için awk kullanabilirsiniz:

$ 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

ayrıntılar

Awk satırı şu şekilde çalışır: aher BEGIN:VCARDsatırda artırılan sayaç ve aynı zamanda çıktı dosya adı sprintf (içinde depolanan fn) kullanılarak oluşturulur. Her satır için geçerli satır ( $0) geçerli dosyaya (adlandırılmış fn) eklenir .

Sonuncusu başarılı olduğu echo $?anlamına gelir cmp, yani birleştirilmiş tüm tek dosyalar orijinal vcf örneğine eşittir.

Awk içindeki çıkış yeniden yönlendirmesinin kabuktan farklı çalıştığını unutmayın. Bu, > fnawk ile önce dosyanın zaten açık olup olmadığını kontrol ettiği anlamına gelir . Zaten açıksa, awk ona eklenir . Değilse, açılır ve keser.

Bu yeniden yönlendirme mantığı nedeniyle , örtülü olarak açılan dosyaları açıkça kapatmamız gerekir, aksi takdirde çağrı, giriş dosyasının çok sayıda kayıt içerdiği durumlarda açık dosya sınırına ulaşacaktır.


Awk içinde çok fazla açık dosya hatasını önlemek için dosyayı kapatmanız gerekir. stackoverflow.com/questions/32878146/… Böylece komut şöyle olur: gawk '/ BEGIN: VCARD / {close (fn); ++, bir; fn = sprintf ("kart_% 02d.vcf", a); print "Yazma:", fn} {print $ 0 >> fn; } 'example.vcf
Dan Bennett

@DanBennett İpucu için çok teşekkür ederim! Cevabımı güncelledim ve yönlendirme mantığı / sabit yönlendirme ile ilgili notları da basitleştirdim.
maxschlepzig


5

Csplit'in Gnu sürümü uzantıyı ayarlayabilir - Ignacio'nun cevabı Bence en özlüdür, sadece uzantıyı almak için en son ince ayarın gerekli olduğunu - 'printf' formatını kullanarak:

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

GNU csplitMAN sayfasındaki ilgili pasaj :

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

Mac kullanıyordum ve bunun yerine gcsplit'i kullanmak biraz zaman aldı, ama bir kez yaptım bu cevap bana yardımcı oldu.
Luke Gedeon

4

İşi yapmak için bu komut dosyasını kullanabilirsiniz. Buna split-vcf-file denir .

Örnek kullanım

$ 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

Komut dosyasını çalıştırmak için:

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

split_vcf.pl bir windows sürümüdür. unix için dosya adlarına "\" ekleyen alt make_filename'i değiştirin.
J Dan

4

GNU Paralel kullanarak şunları yapabilirsiniz:

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

Veya http://oletange.blogspot.com/2013/10/useless-use-of-cat.html dosyasını çürütebilirsiniz , bunun yerine bunu kullanabilirsiniz:

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

Daha fazla örneğe bakın: http://www.gnu.org/software/parallel/man.html

Giriş videolarını izleyin: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

10 saniye kurulum:

$ (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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.