Làm thế nào tôi có thể rút ngắn một tập tin từ dòng lệnh?


9

Tôi có một tệp xml 150 GB mà tôi muốn rút ngắn (tức là cắt ngắn) xuống còn khoảng 1 GB - có một lệnh đơn giản (bash hoặc tương tự) mà tôi có thể sử dụng hoặc tôi phải đi theo con đường lập trình (chỉnh sửa nó trong vi hoặc emacs là một cơn ác mộng ngay cả trên các hệ thống sắt lớn)?

.


1
Bạn có nghĩa là bạn muốn cắt bớt tập tin, hoặc bạn muốn xóa thông tin trong toàn bộ tập tin?
AFH

1
Tìm thấy điều này trên SO; stackoverflow.com/a/15934078/2800918 .
CAB

2
Vì đây là tệp XML, mà tôi giả sử chứa một chuỗi có số lượng phần tử lớn, nên bạn cũng có thể sử dụng ngôn ngữ chuyển đổi XML như XQuery để lọc ra một số phần tử nhất định, có lợi thế để xuất XML hợp lệ ( Ví dụ )
Aaron

4
Tập tin vẫn cần phải là XML hợp lệ khi hoàn thành?
Joe

1
không, tôi vừa vá nó như vậy
adrianmcmenamin

Câu trả lời:


15

Giả sử bạn muốn cắt bớt và trích xuất 1 GB đầu tiên của tệp 150 GB:

Với head:

head -c 1G infile > outfile

Lưu ý rằng Ghậu tố có thể được thay thế bằng GBđể căn chỉnh thành 1000 thay vì 1024.

Hoặc với dd:

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

Hoặc như trong câu trả lời của Wumpus Q. Wumbley, ddcó thể cắt ngắn tại chỗ.


5
Điều đó có thể sẽ không dẫn đến một tệp XML có thể đọc được khi hoàn thành.
Joe

3
@Joe - OP không yêu cầu một tệp có thể đọc được (họ cũng không nói nó có thể đọc được). Họ đã nói rằng họ không quan tâm đến việc mất thông tin. Tôi sẽ mong đợi một câu hỏi mới từ OP về cách sửa tệp nói.
KevinDTimm

3
Tôi biết đủ xml để sửa nó, tôi đã viết DTD cho định dạng!
adrianmcmenamin

37

Để cắt một tệp thành 1 gigabyte, hãy sử dụng truncatelệnh:

truncate -s 1G file.xml

Kết quả của việc cắt bớt có thể sẽ không phải là một tệp XML hợp lệ nhưng tôi tập hợp rằng bạn hiểu điều đó.

Tài liệu dành cho phiên bản GNU của truncateở đây và tài liệu hướng dẫn cho phiên bản BSD là đây


14

Nếu có thể, tôi sẽ sử dụng truncatelệnh như trong câu trả lời của John1024. Tuy nhiên, đây không phải là một lệnh unix tiêu chuẩn, vì vậy một ngày nào đó bạn có thể thấy mình không thể sử dụng nó. Trong trường hợp đó, ddcó thể thực hiện cắt ngắn tại chỗ quá.

ddHành vi mặc định của nó là cắt bớt tệp đầu ra tại điểm kết thúc sao chép, vì vậy bạn chỉ cần cung cấp cho nó tệp đầu vào có độ dài 0 và yêu cầu nó bắt đầu ghi tại điểm cắt ngắn mong muốn:

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

(Điều này không giống với bản sao và cắt bớt ddtrong câu trả lời của multithr3at3d.)

Lưu ý rằng tôi đã sử dụng 1048576 và 1024 vì 1048576 * 1024 là kích thước mong muốn. Tôi tránh bs = 1m bởi vì đây là một "di động" câu trả lời, và cổ điển ddchỉ biết hậu tố k, bw.


2
Đối với giải pháp chung, có lẽ bạn nên lưu ý rằng bssố nhân với seeksố đó là số byte cần giữ. Bất kỳ hai số thỏa mãn ràng buộc đó sẽ hoạt động; ví dụ, bs=1073741824 seek=1hoặc bs=1 seek=1073741824. Hoặc, vì bsmặc định là 512, seek=2097152một mình cũng nên hoạt động. Và bạn có thể sử dụng ký hiệu như 1M, 1K, 1G2M.
G-Man nói 'Phục hồi Monica'

1

Tôi không hoàn toàn chắc chắn những gì bạn đang hỏi. Bạn chỉ muốn loại bỏ 149 GB khác hay bạn đang cố nén 150 GB thành 1 GB? Bất kể, đây có thể là một phương pháp hữu ích để thực hiện điều này.

Các splitlệnh có thể chia nhỏ bất kỳ tập tin thành nhiều phần. Thấy người đàn ông chia tay . Bạn có thể chỉ định kích thước của các khối tệp bạn muốn chia nó thành -btùy chọn. Ví dụ:

$ split -b 1GB myfile.xml

Nếu không có bất kỳ tùy chọn nào khác, điều này sẽ tạo ra một số tệp trong thư mục hiện tại bắt đầu bằng chữ cái x. Nếu bạn muốn điều chỉnh tên của các tệp tách, hãy tham khảo trang man.

Để lắp ráp lại tập tin chỉ cần sử dụng cat * > re-assembled.xml.

Thí dụ:

[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

Cuối cùng, tôi chỉ sử dụng sedđể trích xuất một số dòng tùy ý:

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

1
Đặt sang một bên liệu điều này có trả lời câu hỏi hay không, điều này sẽ quét toàn bộ tập tin, vì vậy nó sẽ hiệu quả hơn khi sử dụng sed 1000000q(và nói gọn hơn một chút, nói một cách trực quan).
Lớp B
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.