Cách tốt nhất để tham gia lại các tập tin sau khi tách chúng là gì?


73

Nếu tôi có một tệp lớn và cần chia nó thành 100 megabyte, tôi sẽ làm

split -b 100m myImage.iso

Điều đó thường cho tôi một cái gì đó như

xaa
xab
xac
xad

Và để đưa chúng trở lại với nhau, tôi đã sử dụng

cat x* > myImage.iso

Có vẻ như nên có một cách hiệu quả hơn là đọc qua từng dòng mã trong một nhóm tệp catvà chuyển hướng đầu ra sang một tệp mới. Giống như một cách chỉ mở hai tệp, xóa EOFđiểm đánh dấu khỏi tệp đầu tiên và kết nối chúng - mà không phải thông qua tất cả nội dung.

Windows / DOS có lệnh sao chép các tệp nhị phân. Trợ giúp đề cập rằng lệnh này được thiết kế để có thể kết hợp nhiều tệp. Nó hoạt động với cú pháp này: ( /bdành cho chế độ nhị phân)

copy /b file1 + file2 + file3 outputfile

Có điều gì tương tự hoặc cách tốt hơn để tham gia các tệp lớn trên Linux so với mèo không?

Cập nhật

catTrên thực tế , đó có vẻ là cách đúng đắn và tốt nhất để tham gia các tệp. Vui mừng khi biết tôi đã sử dụng đúng lệnh trong suốt :) Cảm ơn mọi người đã phản hồi.


22
Lưu ý bên lề: Tốt hơn không sử dụng cat x*, vì thứ tự của các tệp phụ thuộc vào cài đặt ngôn ngữ của bạn. Bắt đầu nhập tốt hơn cat x, nhấn Esc và sau đó *- bạn sẽ thấy thứ tự các tệp được mở rộng và có thể sắp xếp lại.
rozcietrzewiacz

16
Thay vì cat x*bạn có thể xem xét mở rộng nẹp vỏ, cat xa{a..g}mở rộng trình tự được chỉ định thành cat xaa xab xac xad xae xaf xag
Peter.O

3
@rozcietrzewiacz - bạn có thể cho một ví dụ về cách tôi sẽ điều chỉnh cài đặt ngôn ngữ của mình sẽ bị hỏng cat x*không? Cài đặt ngôn ngữ mới sẽ không ảnh hưởng đến splitviệc nếu splitcat x*được sử dụng trên cùng một hệ thống, chúng sẽ luôn hoạt động?
cwd

3
"mở hai tệp, xóa điểm đánh dấu EOF khỏi tệp đầu tiên và kết nối chúng - mà không phải thông qua tất cả nội dung." ... có vẻ như bạn cần phát minh ra một hệ thống tệp mới để làm những gì bạn muốn
JoelFan

6
@cwd: Nhìn vào split.cGNU Coreutils, các hậu tố được xây dựng từ một mảng ký tự cố định : static char const *suffix_alphabet = "abcdefghijklmnopqrstuvwxyz";. Hậu tố sẽ không bị ảnh hưởng bởi miền địa phương. (Nhưng tôi không nghĩ rằng bất kỳ miền địa phương lành mạnh nào sẽ sắp xếp lại các chữ cái viết thường; ngay cả EBCDIC vẫn duy trì trật tự tiêu chuẩn của họ.)
Keith Thompson

Câu trả lời:


50

Đó chỉ là những gì catđã được thực hiện cho. Vì nó là một trong những công cụ GNU lâu đời nhất, tôi nghĩ rằng rất khó có công cụ nào khác làm điều đó nhanh hơn / tốt hơn. Và nó không phải là đường ống - nó chỉ chuyển hướng đầu ra.


Thủ cat x, then press Escthuật mà bạn đề cập rất gọn gàng .. Tôi đã tìm kiếm một thứ như thế, cảm ơn ... bình luận tốt và câu trả lời hay
Peter.O 15/11/11

2
Bạn được chào đón :) Ngoài ra, khi bạn có danh sách các tệp đó trên dòng lệnh, bạn có thể sử dụng Ctrl+Wđể cắt ra một từ và sau đó Ctrl+Ydán nó.
rozcietrzewiacz

mèo có nghĩa là "concatenate"
JoelFan

4
.. và "catenate" bắt nguồn từ một từ "catena" trong tiếng Latin có nghĩa là "một chuỗi" .. nối liền là nối các liên kết của một chuỗi. ... (và xa hơn một chút ngoài chủ đề, một đường cong dây xích cũng xuất phát từ "catena". Đó là cách một chuỗi treo)
Peter.O

19

Dưới mui xe

Không có cách nào hiệu quả hơn là sao chép tệp đầu tiên, sau đó sao chép tệp thứ hai sau nó, v.v. Cả DOS copycatlàm điều đó.

Mỗi tệp được lưu trữ độc lập với các tệp khác trên đĩa. Hầu như mọi hệ thống tập tin được thiết kế để lưu trữ dữ liệu trên một thiết bị giống như đĩa hoạt động theo các khối. Đây là một bản trình bày rất đơn giản về những gì xảy ra: đĩa được chia thành các khối, giả sử là 1kB và với mỗi tệp, hệ điều hành sẽ lưu danh sách các khối tạo nên nó. Hầu hết các tệp không có số nguyên khối dài, vì vậy khối cuối cùng chỉ bị chiếm một phần. Trong thực tế, các hệ thống tệp có nhiều tối ưu hóa, chẳng hạn như chia sẻ khối một phần cuối cùng giữa một số tệp hoặc lưu trữ các khối 46798 đến 47913, thay vì khối 46798, khối 46998, khối Hồi. Khi hệ điều hành cần tạo một tệp mới, nó sẽ tìm các khối miễn phí. Các khối không phải liên tiếp: nếu chỉ các khối 4, 5, 98 và 178 là miễn phí, bạn vẫn có thể lưu trữ tệp 4kB.

Bạn có thể hỗ trợ các khối một phần ở giữa tệp, nhưng điều đó sẽ tăng thêm độ phức tạp đáng kể, đặc biệt là khi truy cập các tệp không tuần tự: để chuyển sang byte thứ 10340, bạn không còn có thể nhảy đến byte thứ 100 của khối thứ 11, bạn sẽ có để kiểm tra độ dài của mỗi khối can thiệp.

Với việc sử dụng các khối, bạn không thể tham gia hai tệp, vì nói chung, tệp đầu tiên kết thúc ở giữa khối. Chắc chắn, bạn có thể có một trường hợp đặc biệt, nhưng chỉ khi bạn muốn xóa cả hai tập tin khi nối. Đó sẽ là một xử lý đặc biệt cao cho một hoạt động hiếm. Việc xử lý đặc biệt như vậy không tồn tại một mình, bởi vì trên một hệ thống tệp thông thường, nhiều tệp đang được truy cập cùng một lúc. Vì vậy, nếu bạn muốn thêm một tối ưu hóa, bạn cần suy nghĩ cẩn thận: điều gì xảy ra nếu một quá trình khác đang đọc một trong các tệp liên quan? Điều gì xảy ra nếu ai đó cố gắng nối A và B trong khi ai đó đang nối A và C? Và như vậy. Nói chung, việc tối ưu hóa hiếm có này sẽ là một gánh nặng rất lớn.

Nói chung, bạn không thể làm cho việc tham gia các tệp hiệu quả hơn mà không phải hy sinh lớn ở nơi khác. Nó không đáng.

Chia tách và tham gia

splitcatlà những cách đơn giản để chia và nối các tập tin. splitđảm nhiệm việc sản xuất các tệp có tên theo thứ tự bảng chữ cái, để cat *hoạt động tham gia.

Một nhược điểm của catviệc tham gia là nó không mạnh đối với các chế độ thất bại phổ biến. Nếu một trong các tệp bị cắt ngắn hoặc bị thiếu, catsẽ không khiếu nại, bạn sẽ chỉ nhận được đầu ra bị hỏng.

Có các tiện ích nén tạo ra lưu trữ nhiều phần, chẳng hạn như zipsplitrar -v. Chúng không bị lẫn lộn, bởi vì chúng nén và đóng gói (lắp ráp nhiều tệp thành một) ngoài việc tách (và ngược lại giải nén và giải nén ngoài việc tham gia). Nhưng chúng hữu ích ở chỗ họ xác minh rằng bạn có tất cả các phần và các phần đó đã hoàn tất.


8

Có vẻ như nên có một cách hiệu quả hơn là dẫn tất cả nội dung qua hệ thống stdin/stdout

Ngoại trừ đó không thực sự là những gì đang xảy ra. Shell đang kết nối thiết bị xuất chuẩn cat trực tiếp với tệp đang mở, điều đó có nghĩa là "đi qua thiết bị xuất chuẩn" giống như ghi vào đĩa.


Tôi chỉ tưởng tượng sử dụng con mèo để hiển thị vài gigabyte mã trong bảng điều khiển, sau đó bắt nó và đưa vào một tập tin. Đó là hình ảnh tinh thần tôi có cho những gì phải xảy ra khi tôi sử dụng mèo và chuyển hướng đầu ra mà tôi không thể nhìn thấy. Có vẻ như nếu có một cách bạn có thể mở hai tệp, kết nối chúng và sau đó đóng chúng thì sẽ hiệu quả hơn là chạy qua tất cả các dòng mã với cat. Cảm ơn đã cho tôi biết về kết nối trực tiếp.
cwd

@cwd Có thể thiết kế một hệ thống tệp trong đó bạn có thể tham gia hai tệp theo cách đó, nhưng điều đó sẽ làm phức tạp thiết kế của hệ thống tệp vô cùng. Bạn sẽ tối ưu hóa cho một thao tác đó với chi phí thực hiện nhiều tác vụ phổ biến phức tạp hơn và chậm hơn.
Gilles

@Gilles - thật thú vị khi biết thêm về các chi tiết cấp thấp. Đối với tôi, việc đọc tất cả các cung từ đĩa cứng cho một số tệp và sau đó đưa chúng trở lại các khu vực không sử dụng khác trên đĩa có vẻ không hiệu quả. Và tôi nghĩ rằng các tệp lớn phải được lưu trữ trên nhiều khối của các lĩnh vực miễn phí bởi vì có thể không phải lúc nào cũng có đủ các khối cạnh nhau để lưu trữ chúng. Do đó, về mặt lý thuyết, bạn có thể nối các tệp thành một bằng cách xóa dấu EOF và trỏ đến nhóm các ngành khi bắt đầu tệp tiếp theo. * nix rất mạnh nên tôi tự hỏi liệu có cách nào tốt hơn mèo không.
cwd

@cwd Không có điểm đánh dấu EOF nào. Không có hệ thống tập tin hiện đại lành mạnh nào hoạt động như vậy, bởi vì nó ngăn chặn một số ký tự xuất hiện trong các tệp (hoặc nếu không yêu cầu mã hóa phức tạp). Nhưng ngay cả khi có một điểm đánh dấu EOF, hầu hết thời gian, bạn sẽ không có tệp đúng sau nó.
Gilles

Ý tôi là khái niệm về điểm đánh dấu EOF chứ không phải điểm đánh dấu EOF thực tế. Mặt khác, nếu bạn nhìn vào các bit và byte của một tệp trên ổ cứng, làm sao bạn biết nó kết thúc ở đâu? Bạn có chỉ định độ dài của tập tin khi bắt đầu nó không? Tôi đang nói về một điều thực sự cấp thấp. Có phải đó là những gì bạn cũng đang đề cập đến?
cwd

3

Tôi đã từng có chính xác vấn đề này: Tôi muốn tham gia một số tệp, nhưng không đủ dung lượng đĩa để giữ chúng gấp đôi.

Vì vậy, tôi đã viết một loạt các chương trình:

  • một để "hút" một tập tin bằng cách đọc nó, gửi nó đến thiết bị xuất chuẩn và nếu hoàn thành, hãy xóa nó
  • và một để đệm dữ liệu "nhanh chóng".

Điều này cho phép tôi làm một cái gì đó như

partto sourcefile | mybuffer 128M >>cumufile

và do đó loại bỏ tệp nguồn trong khi 128M vẫn chưa được đăng ký. Một chút nguy hiểm, nhưng nếu dữ liệu không phải là quý giá, hoặc chúng tồn tại ở một nơi khác, điều đó là khả thi.

Nếu cần, tôi có thể cung cấp nguồn.


0

Về mặt kỹ thuật, đây là cách truy cập toàn bộ tệp mà không cần phải đọc và ghi toàn bộ nội dung và có thể hữu ích cho các tệp lớn hoặc nếu còn ít dung lượng:

$ mkfifo myImage.iso
$ cat xa{a..g} > myImage.iso &

Và sau đó sử dụng myImage.iso, ví dụ

$ md5sum myImage.iso

Mặc dù tất nhiên myImage.isolà một tệp đặc biệt (tên ống) và không phải là tệp thông thường, vì vậy đây có thể là sử dụng hay không tùy thuộc vào những gì bạn đang cố gắng làm.


0

Chia tách tập tin

Chia theo kích thước

Nếu bạn muốn chia tệp lớn thành các tệp nhỏ và chọn tên và kích thước của tệp đầu ra nhỏ thì đây là cách.

split -b 500M videos\BigVideoFile.avi SmallFile.

Theo cách này, bạn chọn tách một tệp lớn thành các phần nhỏ hơn 500 MB. Ngoài ra, bạn muốn tên của các phần của tệp là SmallFile. Lưu ý rằng bạn cần chấm sau tên tập tin. Kết quả sẽ tạo ra các tệp mới như thế này:

SmallFile.ab SmallFile.ad SmallFile.af SmallFile.ah SmallFile.aj
SmallFile.aa SmallFile.ac SmallFile.ae SmallFile.ag SmallFile.ai SmallFile.ak
...

Chia theo số dòng

Bằng cách này, bạn sẽ chia tệp văn bản thành các tệp nhỏ hơn giới hạn ở 50 dòng.

split -l 50 text_to_split.txt

Kết quả sẽ giống như thế này:

xaa xab xac ...

Tách theo byte

Chia thành các tệp nhỏ với kích thước tùy chỉnh của các tệp nhỏ theo byte:

split -b 2048 BigFile.mp4

Kết quả phải tương tự với kết quả từ Chia tách theo số dòng .

Tập tin tham gia

Bạn có thể tham gia các tập tin theo hai cách. Đầu tiên là:

cat SmallFile.* > OutputBigVideoFile.avi

Hoặc với:

cat SmallFile.?? > OutputBigVideoFile.avi

Lưu ý: Khi bạn đang tham gia các tệp, các tệp nhỏ không bị hỏng. Ngoài ra tất cả các tệp nhỏ (một phần) phải nằm trong cùng một thư mục.

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.