ฉันจะย่อไฟล์จากบรรทัดคำสั่งได้อย่างไร


9

ฉันมีไฟล์ 150GB xml ที่ฉันต้องการย่อให้สั้นลง (เช่นตัด) เป็นประมาณ 1GB - มีคำสั่ง (ทุบตีหรือคล้ายกัน) ที่ฉันสามารถใช้ได้หรือฉันต้องใช้เส้นทางการเขียนโปรแกรม (แก้ไขใน vi หรือ emacs) เป็นฝันร้ายแม้แต่ในระบบเหล็กขนาดใหญ่)?

(ฉันไม่กังวลเกี่ยวกับการสูญหายของข้อมูลโดยเฉพาะฉันต้องการไฟล์ที่สั้นกว่าเพื่อให้ฉันสามารถทดสอบซอฟต์แวร์ในส่วนนี้และไม่ต้องรอคำตอบนานหลายชั่วโมงไฟล์ที่สั้นกว่าจะทำให้ฉันทำเช่นนั้น)


1
คุณหมายถึงคุณต้องการตัดทอนไฟล์หรือคุณต้องการลบข้อมูลออกจากไฟล์หรือไม่?
AFH

1
พบสิ่งนี้ใน SO; stackoverflow.com/a/15934078/2800918
CAB

2
เนื่องจากนี่คือไฟล์ XML ซึ่งฉันถือว่ามีลำดับที่มีองค์ประกอบจำนวนมากคุณยังสามารถใช้ภาษาการแปลง XML เช่น XQuery เพื่อกรององค์ประกอบเหล่านี้จำนวนหนึ่งซึ่งจะมีประโยชน์ในการแสดงผล XML ที่ถูกต้อง ( ตัวอย่าง )
Aaron

4
ไฟล์ยังต้องเป็น XML ที่ถูกต้องเมื่อทำเสร็จหรือไม่
Joe

1
ไม่ฉันเพิ่งปรับปรุงมันดังนั้น
adrianmcmenamin

คำตอบ:


15

สมมติว่าคุณต้องการตัดและแยกไฟล์ 1 GB แรกจาก 150 ไฟล์:

ด้วยhead:

head -c 1G infile > outfile

โปรดทราบว่าGคำต่อท้ายสามารถถูกแทนที่ด้วยGBเพื่อจัดเรียงเป็น 1,000 แทน 1024

หรือด้วยdd:

dd if=infile of=outfile bs=1M count=1024

หรือเช่นเดียวกับใน Wumpus Q. คำตอบของ Wumble ddสามารถตัดทอนได้


5
ซึ่งอาจไม่ส่งผลให้ไฟล์ XML อ่านได้เมื่อดำเนินการเสร็จ
Joe

3
@Joe - OP ไม่ได้ร้องขอไฟล์ที่อ่านได้ (หรือพวกเขาบอกว่ามันไม่สามารถอ่านได้) พวกเขาบอกว่าพวกเขาไม่สนใจที่จะสูญเสียข้อมูล ฉันคาดว่าจะมีคำถามใหม่จาก OP เกี่ยวกับวิธีแก้ไขไฟล์ดังกล่าว
KevinDTimm

3
ฉันรู้พอที่จะแก้ไขมันฉันเขียน DTD สำหรับรูปแบบ!
adrianmcmenamin

37

หากต้องการตัดไฟล์เป็น 1 กิกะไบต์ให้ใช้truncateคำสั่ง:

truncate -s 1G file.xml

ผลลัพธ์ของการตัดจะไม่เป็นไฟล์ XML ที่ถูกต้อง แต่ฉันรวบรวมว่าคุณเข้าใจ

เอกสารสำหรับรุ่น GNU truncateอยู่ที่นี่และเอกสารสำหรับรุ่น BSD อยู่ที่นี่


14

ถ้าเป็นไปได้ฉันจะใช้truncateคำสั่งเหมือนในคำตอบของ John1024 มันไม่ใช่คำสั่ง unix มาตรฐานดังนั้นบางวันคุณอาจพบว่าตัวเองไม่สามารถใช้งานได้ ในกรณีนั้นddสามารถทำการตัดทอนในสถานที่ได้เช่นกัน

ddพฤติกรรมเริ่มต้นของการตัดทอนไฟล์ที่จุดสิ้นสุดการคัดลอกดังนั้นคุณเพียงแค่ให้ไฟล์อินพุต 0 ความยาวและบอกให้เริ่มเขียนที่จุดตัดทอนที่ต้องการ:

dd if=/dev/null of=filename bs=1048576 seek=1024

(นี่ไม่เหมือนกับการคัดลอกและตัดddในคำตอบของ multithr3at3d)

โปรดทราบว่าฉันใช้ 1048576 และ 1024 เพราะ 1048576 * 1024 เป็นขนาดที่ต้องการ ฉันหลีกเลี่ยง BS = 1m เพราะนี่คือ "พกพา" คำตอบและคลาสสิกddเท่านั้นที่รู้คำต่อท้ายk, และbw


2
สำหรับการแก้ปัญหาทั่วไปคุณควรทราบว่าbsจำนวนที่คูณด้วยseekจำนวนนั้นเป็นจำนวนไบต์ที่จะเก็บไว้ ตัวเลขสองตัวใด ๆ ที่มีคุณสมบัติตรงตามข้อ จำกัด เช่นหรือbs=1073741824 seek=1 bs=1 seek=1073741824หรือตั้งแต่bsค่าเริ่มต้นที่ 512 seek=2097152เพียงอย่างเดียวก็ควรทำงานเช่นกัน และคุณสามารถใช้สัญกรณ์เช่น1M, 1K, และ1G 2M
G-Man กล่าวว่า 'Reinstate Monica'

1

ฉันไม่แน่ใจว่าสิ่งที่คุณถาม คุณต้องการกำจัด 149GB อื่น ๆ หรือคุณพยายามบีบอัด 150GB เป็น 1 GB หรือไม่? นี่อาจเป็นวิธีที่มีประโยชน์ในการทำสิ่งนี้ให้สำเร็จ

splitคำสั่งสามารถแยกไฟล์ใด ๆ ที่เป็นหลายชิ้น ดูคนแยก คุณสามารถระบุขนาดของไฟล์ไฟล์ที่คุณต้องการแบ่งออกเป็น-bตัวเลือก ตัวอย่างเช่น

$ split -b 1GB myfile.xml

โดยไม่มีตัวเลือกอื่น ๆ xนี้ควรสร้างหลายแฟ้มในไดเรกทอรีปัจจุบันเริ่มต้นด้วยตัวอักษร หากคุณต้องการปรับชื่อของไฟล์แยกดูที่หน้าคน

cat * > re-assembled.xmlอีกครั้งประกอบไฟล์เพียงแค่การใช้งาน

ตัวอย่าง:

[kent_x86.py@c7 split-test]$ ls -l opendocman*
-rw-rw-r--.  1 kent_x86.py kent_x86.py 2082602 Mar 31  2017 opendocman-1.3.5.tar.gz

[kent_x86.py@c7 split-test]$ split -b 100K opendocman-1.3.5.tar.gz 
[kent_x86.py@c7 split-test]$ ls
opendocman-1.3.5.tar.gz  xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj  xak  xal  xam  xan  xao  xap  xaq  xar  xas  xat  xau
[kent_x86.py@c7 split-test]$ ll
total 4072
-rw-rw-r--. 1 kent_x86.py kent_x86.py 2082602 Jan  5 11:06 opendocman-1.3.5.tar.gz
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaa
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xab
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xac
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xad
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xae
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaf
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xag
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xah
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xai
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaj
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xak
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xal
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xam
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xan
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xao
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xap
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaq
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xar
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xas
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xat
-rw-rw-r--. 1 kent_x86.py kent_x86.py   34602 Jan  5 11:06 xau
[kent_x86.py@c7 split-test]$ cat xa* > opendoc-reassembled.tar.gz
[kent_x86.py@c7 split-test]$ ls -l opendoc-reassembled*
-rw-rw-r--. 1 kent_x86.py kent_x86.py 2082602 Jan  5 11:07 opendoc-reassembled.tar.gz


0

ในตอนท้ายฉันเพิ่งใช้sedเพื่อแยกจำนวนบรรทัดโดยพลการ:

sed -n 1,1000000p infile.xml>outfile.xml

1
ฉันเชื่อว่านี่เป็นการตอบคำถามหรือไม่สิ่งนี้จะสแกนไฟล์ทั้งหมดดังนั้นจึงมีประสิทธิภาพมากขึ้นในการใช้sed 1000000q(และมีขนาดกะทัดรัดขึ้นเล็กน้อย
B Layer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.