วิธีแบ่งไฟล์โดยใช้ขอบเขตคำหลัก


15

ฉันมีไฟล์ vcf ที่มี vcards มากมาย

เมื่อนำเข้าไฟล์ vcf ไปยัง outlook ดูเหมือนว่าจะนำเข้า vcard แรกเท่านั้น

ดังนั้นฉันต้องการแยกพวกเขาออก

ระบุว่า vcard เริ่มต้นด้วย

BEGIN:VCARD

และจบลงด้วย

END:VCARD

วิธีที่ดีที่สุดในการแยก vcard แต่ละรายการเป็นไฟล์ของตัวเองคืออะไร

ขอบคุณ

UPDATE

ขอขอบคุณสำหรับการตอบสนองทุก. เช่นเดียวกับคำถามเกี่ยวกับลักษณะนี้มีหลายวิธีในการดูแลแมว นี่คือเหตุผลที่ฉันเลือกสิ่งที่ฉันทำ

ROUND-UP

นี่คือบทสรุปของสิ่งที่ฉันชอบจากแต่ละคำตอบและสิ่งที่ทำให้ฉันเลือกหนึ่งในนั้น

  • csplit: ฉันชอบความกระชับของวิธีนี้จริงๆ ฉันแค่หวังว่ามันจะสามารถตั้งค่านามสกุลไฟล์
  • gawk: ทำทุกอย่างที่ฉันถาม
  • paralell: ทำงานแล้ว แต่ฉันต้องติดตั้งสิ่งใหม่ ๆ (มันก็ตัดสินใจที่จะสร้างใหม่ / bin dir ใน dir บ้านของฉัน)
  • perl: ฉันชอบที่มันสร้าง vcf ตามชื่อของผู้ติดต่อ แต่ตัวเลือก -o ไม่ได้ผลจริงๆ

ข้อสรุป

  • ดังนั้นคนแรกที่จะไปก็perlเพราะมันหักนิดหน่อย
  • ถัดไปเป็นparalellเพราะฉันต้องติดตั้งสิ่งใหม่
  • ต่อไปคือcsplitเพราะเท่าที่ฉันเห็นมันไม่สามารถสร้างส่วนขยายในไฟล์ที่ส่งออก
  • ดังนั้นรางวัลจะเพ่งไปที่การเป็นยูทิลิตี้ที่พร้อมใช้งานและอเนกประสงค์มากพอที่ฉันสามารถสับและเปลี่ยนชื่อไฟล์ได้เล็กน้อย เครื่องหมายโบนัสcmpด้วย :)

คุณลองใช้-bไหม
Ignacio Vazquez-Abrams

คำตอบ:


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 ทำงานแตกต่างจากในเชลล์ นั่นหมายความว่าด้วย> fnawk ตรวจสอบก่อนว่าไฟล์เปิดอยู่หรือไม่ ถ้ามันเปิดอยู่แล้วแล้ว awk ผนวกกับมัน หากไม่เป็นเช่นนั้นจะเปิดขึ้นและตัดทอน

เนื่องจากตรรกะการเปลี่ยนเส้นทางนี้เราต้องปิดไฟล์ที่เปิดอย่างชัดเจนเนื่องจากมิฉะนั้นการโทรจะถึงขีด จำกัด การเปิดไฟล์ในกรณีที่ไฟล์อินพุตมีหลายเรคคอร์ด


คุณจะต้องปิดไฟล์เพื่อหลีกเลี่ยงข้อผิดพลาดของไฟล์ที่เปิดมากเกินไปใน awk stackoverflow.com/questions/32878146/… ดังนั้นคำสั่งจะกลายเป็น: gawk '/ BEGIN: VCARD / {close (fn); ++ นั้น fn = sprintf ("card_% 02d.vcf", a); พิมพ์ "กำลังเขียน:", fn} {พิมพ์ $ 0 >> fn; } 'example.vcf
Dan Bennett

@DanBennett ขอบคุณมากสำหรับคำใบ้! ฉันได้อัปเดตคำตอบของฉันแล้วและยังทำให้ตรรกะการเปลี่ยนเส้นทาง / บันทึกย่อที่เกี่ยวข้องกับการเปลี่ยนเส้นทางง่ายขึ้น
maxschlepzig


5

csplit เวอร์ชัน Gnu สามารถตั้งค่าส่วนขยายได้ - คำตอบของ Ignacio ฉันคิดว่ากระชับที่สุดมันแค่ต้องการบิตสุดท้ายของการปรับแต่งเพื่อรับส่วนขยายโดยใช้รูปแบบ 'printf':

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

นี่คือตัวอย่างข้อมูลที่เกี่ยวข้องจากหน้า gnu csplitman:

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

ฉันใช้ mac และฉันใช้เวลาสักครู่กว่าจะคิดใช้ gcsplit แทน แต่เมื่อฉันตอบคำถามนี้ได้แล้วก็ช่วยฉันได้
Luke Gedeon

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

split_vcf.pl เป็นรุ่น windows สำหรับยูนิกซ์แก้ไข sub 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.