2012-05-24 29 views
10

Tôi đang thử, sử dụng bash, để hợp nhất nội dung của danh sách tệp (hơn 1K) thành tệp lớn.shell - cat - hợp nhất nội dung tệp thành một tệp lớn

Tôi đã thử lệnh cat sau:

cat * >> bigfile.txt 

tuy nhiên những gì lệnh này làm là hợp nhất tất cả mọi thứ, cũng bao gồm những điều đã được sáp nhập.

ví dụ: file1.txt

content1 

file2.txt

content2 

file3.txt

content3 

file4.txt

content4 

bigfile.txt

01.
content1 
content2 
content3 
content2 
content3 
content4 
content2 

nhưng tôi muốn chỉ

content1 
content2 
content3 
content4 

bên trong file .txt

Một cách khác sẽ cat file1.txt file2.txt ... và vân vân ... nhưng tôi không thể làm điều đó cho hơn file 1k!

Cảm ơn sự hỗ trợ của bạn!

Trả lời

18

Vấn đề là bạn đặt bigfile trong cùng một thư mục, do đó biến nó thành một phần của *. Vì vậy, một cái gì đó giống như

cat dir/* > bigfile 

chỉ nên làm việc như bạn muốn nó, với fileN.txt tập tin của bạn nằm ở dir/

+1

... hoặc 'mèo *>/tmp/bigfile; mv/tmp/bigfile .'. – tripleee

+0

Tôi nghĩ rằng fabioln là cố ý bao gồm 'bigfile.txt' trong đầu vào; anh ta muốn thêm vào tệp từ nhiều tệp '.txt' khác nhau, nhưng loại bỏ các bản sao trùng lặp cùng một lúc. – chepner

+0

Cảm ơn các bạn. Vâng, đó là vấn đề! Tôi đặt bigfile trong cùng một thư mục ... vì vậy tôi đã sử dụng lệnh bạn đã cho tôi (cat dir/*> bigfile)! Chỉ cần một câu hỏi khác: tại sao bạn đặt chỉ> thay vì >> là nó giống nhau không? Cảm ơn bạn! – fabioln79

-3

Hãy thử:

cat `ls -1 *` >> bigfile.txt 

Tôi không có một máy unix tiện dụng vào lúc này để kiểm tra nó cho bạn trước.

+2

-1 Điều này không giải quyết được gì và giới thiệu một số vấn đề mới của riêng nó. Không sử dụng 'ls' khi ký tự đại diện đã mở rộng đến các tệp bạn muốn! Không sử dụng các tên tệp không được trích dẫn (đầu ra từ các dấu gạch chéo) vì nó phá vỡ nếu tên tệp chứa khoảng trắng. – tripleee

+0

Tôi đã thực sự nghĩ về một vòng lặp khi tôi đã viết điều đó, nhưng nó đã không đi ra khỏi đầu của tôi đúng cách. Dù sao thì tôi cũng thích câu trả lời của Barton hơn. – JerseyMike

4

Khi đọc lại câu hỏi của bạn, có vẻ như bạn muốn thêm dữ liệu vào bigfile.txt, nhưng mà không thêm trùng lặp. Bạn sẽ phải vượt qua tất cả mọi thứ thông qua sort -u để lọc ra các bản sao:

sort -u * -o bigfile.txt 

Các -o tùy chọn để sắp xếp cho phép bạn một cách an toàn bao gồm các nội dung của bigfile.txt trong đầu vào để sắp xếp trước khi tập tin được ghi đè bằng các đầu ra.

EDIT: Giả sử bigfile.txt được sắp xếp, bạn có thể thử một quá trình hai giai đoạn:

sort -u file*.txt | sort -um - bigfile.txt -o bigfile.txt 

tiên chúng ta sắp xếp các tập tin đầu vào, loại bỏ các bản sao.Chúng tôi đưa ra một quy trình sort -u khác, tùy chọn này sử dụng tùy chọn -m cũng như thông báo cho sort hợp nhất hai tệp được sắp xếp trước đó. Hai tệp chúng tôi sẽ hợp nhất là - (đầu vào chuẩn, luồng đến từ số sort đầu tiên) và chính bản thân số bigfile.txt. Chúng tôi lại sử dụng tùy chọn -o để cho phép chúng tôi ghi lại kết quả đầu ra thành bigfile.txt sau khi chúng tôi đọc nó làm đầu vào.

+0

Tôi đã sửa đổi câu trả lời để cho phép dữ liệu mới được hợp nhất thành 'bigfile.txt' theo cách mà nó vẫn được sắp xếp mà không có bản sao nào được giới thiệu. Tôi nghĩ đây là điều tốt nhất bạn có thể làm mà không cần chuyển sang định dạng có cấu trúc hơn (chẳng hạn như cơ sở dữ liệu). – chepner

4

Bạn có thể giữ các tập tin đầu ra trong cùng thư mục, bạn chỉ cần phải phức tạp hơn một chút so với *:

shopt -s extglob 
cat !(bigfile.txt) > bigfile.txt 
+0

Cảm ơn bạn. Tôi có một câu hỏi liên quan đến lệnh này: thư mục chứa tệp có kích thước 557GB tuy nhiên tệp bigfile được tạo có kích thước 495. Tôi không biết cách giải thích điều này. Tôi đang làm gì sai? Cảm ơn bạn! – fabioln79

+0

@ fabioln79 Với số lượng thông tin được cung cấp, nghi ngờ điều này có thể là do không gian thực sự được sử dụng so với Kích thước khối (Đọc lên sau) – user66001

2

Cách khác sẽ là mèo file1.txt file2.txt .. ... và tôi không thể làm điều đó cho hơn 1k tệp!

Đây là những gì xargs dành cho:

find . -maxdepth 1 -type f -name "file*.txt" -print0 | xargs -0 cat > bigfile.txt 
+0

có xargs thực hiện lệnh cho đối số * mỗi * không? Nếu vậy, bạn nên sử dụng '>>' thay vì '>'? Tôi nghĩ rằng khi nó được thực hiện, bigfile.txt sẽ chỉ chứa nội dung của tập tin cuối cùng được truyền cho nó. – JerseyMike

+1

xargs chạy lệnh một lần cho tất cả các đối số, bạn không cần sử dụng ''>>''. –

+0

Cảm ơn bạn đã làm rõ. Trang người đàn ông không rõ ràng với tôi về nó. – JerseyMike

1

Đây là một câu hỏi cũ nhưng vẫn còn tôi sẽ cung cấp cách tiếp cận khác với xargs

  1. danh sách các tập tin bạn muốn concat

    ls | grep [pattern]> filelist

  2. Xem lại tệp của bạn theo đúng thứ tự với vi hoặc cat. Nếu bạn sử dụng một hậu tố (1, 2, 3, ..., N) này nên không có vấn đề

  3. Tạo file thức

    mèo filelist | xargs mèo >> [file thức]

  4. Tháo filelist

    rm -f filelist

Hope this helps ai

Các vấn đề liên quan