Làm cách nào để nối một tệp này với tệp khác trong Linux từ trình bao?


418

Tôi có hai tập tin: file1file2. Làm thế nào để tôi nối các nội dung của file2để file1nội dung của file1quá trình tiếp tục?

Câu trả lời:


611

Sử dụng chuyển hướng bash dựng sẵn (tldp) :

cat file2 >> file1

2
Làm thế nào để bạn làm nó tập tin đích không thuộc sở hữu của bạn và bạn cần sử dụng sudo?
Bijay Rungta

1
@BijayRungta: Có vẻ như bạn đã trả lời câu hỏi của riêng bạn. Bạn muốn pre-Pend sudovào catlệnh (và nhập thông tin nếu được nhắc).
David

bạn cần ... chmod 777 / etc / default / docker để cung cấp cho mình quyền ghi trên tệp đó - hãy chắc chắn khôi phục quyền truy cập tệp cũ sau khi thực hiện
danday74

1
@Sigur: Trừ khi có một cách để hướng đầu ra vào hai tệp cùng một lúc, nó sẽ liên quan đến hai lệnh của lệnh.
David

2
@Sigur hoặc có một cái nhìn vào teechương trình : cat 1 | tee -a 2 3. Bạn có thể đặt bao nhiêu tệp tùy thích sau khi chuyển đổi --append(hoặc -aviết tắt).
Stefan van den Akker

291

cat file2 >> file1

Các >>nhà khai thác gắn thêm đầu ra cho các tập tin có tên hoặc tạo ra các tập tin có tên nếu nó không tồn tại.

cat file1 file2 > file3

Điều này nối hai hoặc nhiều tệp thành một. Bạn có thể có nhiều tệp nguồn như bạn cần. Ví dụ,

cat *.txt >> newfile.txt

Cập nhật 20130902
Trong các bình luận, eumiro gợi ý "đừng thử cat file1 file2 > file1." Lý do điều này có thể không dẫn đến kết quả mong đợi là tệp nhận chuyển hướng được chuẩn bị trước khi lệnh bên trái của lệnh >được thực thi. Trong trường hợp này, đầu tiên file1được cắt ngắn thành độ dài bằng 0 và được mở cho đầu ra, sau đó catlệnh cố gắng nối tệp hiện có độ dài bằng không cộng với nội dung file2vào file1. Kết quả là nội dung ban đầu file1bị mất và ở vị trí của nó là một bản sao file2mà có lẽ không như mong đợi.

Cập nhật 20160919
Trong các bình luận, tpartee đề nghị liên kết với các nguồn / thông tin sao lưu. Để tham khảo có thẩm quyền, tôi hướng người đọc tốt bụng đến trang sh man tại linuxcommand.org, trong đó nêu rõ:

Trước khi một lệnh được thực thi, đầu vào và đầu ra của nó có thể được chuyển hướng bằng cách sử dụng một ký hiệu đặc biệt được giải thích bởi shell.

Trong khi điều đó nói với người đọc những gì họ cần biết thì rất dễ bỏ lỡ nếu bạn không tìm kiếm nó và phân tích cú pháp từng câu. Từ quan trọng nhất ở đây là "trước". Việc chuyển hướng được hoàn thành (hoặc thất bại) trước khi lệnh được thực thi.

Trong trường hợp ví dụ của cat file1 file2 > file1shell thực hiện chuyển hướng trước tiên để các tay cầm I / O được đặt đúng chỗ trong môi trường mà lệnh sẽ được thực thi trước khi nó được thực thi.

Một phiên bản thân thiện hơn trong đó ưu tiên chuyển hướng được trình bày theo chiều dài có thể được tìm thấy tại trang web của Ian Allen dưới dạng phần mềm khóa học Linux. Trang Ghi chú chuyển hướng I / O của anh ấy có nhiều điều để nói về chủ đề này, bao gồm cả việc quan sát rằng chuyển hướng hoạt động ngay cả khi không có lệnh. Truyền cái này vào cái vỏ:

$ >out

... Tạo một tập tin trống có tên. Shell trước tiên thiết lập chuyển hướng I / O, sau đó tìm kiếm một lệnh, không tìm thấy và hoàn thành thao tác.


17
@asir - đừng thử cat file1 file2 > file1- điều này sẽ không hoạt động như bạn có thể đang chờ.
eumiro

5
Thật ra đây chính xác là những gì anh ấy cần. Ông nói "không ghi đè lên tập tin hiện tại1." Ba người trả lời đầu tiên đã hoàn toàn bỏ qua phần này của câu hỏi và đề nghị một lệnh sử dụng >>sẽ sửa đổi các tập tin file1. T.Rob đã làm một công việc vượt trội hơn nhiều là giải thích câu trả lời của mình thay vì chỉ chạy đua để gửi một cái gì đó, trên thực tế, không chính xác. Dựa trên văn bản của câu hỏi, tôi tin rằng đó cat file1 file2 > file3là lệnh thích hợp mà @asir đang tìm kiếm.
dm78

Cảm ơn những lời tốt đẹp, David! Những gì @eumiro chỉ ra ở trên nhưng không đi sâu vào chi tiết là hoạt động ở bên phải của hoạt động >được thực hiện trước tiên. Vì vậy, việc thực thi cat file1 file2 > file1đầu tiên sẽ ghi đè file1sau đó cố gắng sao chép tệp có độ dài bằng không vào chính nó. Điều này có ý nghĩa khi bạn nghĩ về thứ tự các hoạt động có thể và nên xảy ra nhưng đủ tinh tế để khiến nhiều người ngạc nhiên. Vì vậy, nếu không có gì khác, eumiro và bạn đã nhắc cải thiện thêm cho câu trả lời. Cảm ơn vì điều đó!
T.Rob

Ngoài ra, đừng thử dùng tệp cat1
Hendra Uzia

Ngoài ra, chỉ cần làm cho nó ngắn gọn hơn một chút, nếu "tệp mới" đã tồn tại, hãy >> thêm vào tệp và > thay thế tệp.
rinogo

43

Lưu ý : nếu bạn cần sử dụng sudo , hãy làm điều này:

sudo bash -c 'cat file2 >> file1'

Phương pháp thông thường chỉ đơn giản là chuẩn bị trước sudolệnh sẽ thất bại, vì sự leo thang đặc quyền không chuyển sang chuyển hướng đầu ra.


6
Một thành ngữ phổ biến khác cho điều này làcat file2 | sudo tee -a file1 > /dev/null
ianw


13

Chỉ để tham khảo, sử dụng ddresTHER cung cấp một cách gián đoạn để đạt được nhiệm vụ nếu, ví dụ, bạn có các tệp lớn và cần phải tạm dừng và sau đó tiếp tục tại một số điểm sau:

ddrescue -o $(wc --bytes file1 | awk '{ print $1 }') file2 file1 logfile

Đây logfilelà bit quan trọng. Bạn có thể làm gián đoạn quá trình với Ctrl-Cvà tiếp tục nó bằng cách chỉ định lại chính xác cùng một lệnh và ddresTHER sẽ đọc logfilevà tiếp tục từ nơi nó rời đi. Các -o Alá cờ nói ddrescue bắt đầu từ byte Một trong file đầu ra ( file1). Vì vậy, wc --bytes file1 | awk '{ print $1 }'chỉ cần trích xuất kích thước của file1byte (bạn có thể chỉ cần dán vào đầu ra từ lsnếu bạn muốn).

Như được chỉ ra bởi ngks trong các bình luận, nhược điểm là ddresTHER có thể sẽ không được cài đặt theo mặc định, vì vậy bạn sẽ phải cài đặt thủ công. Một điều phức tạp khác là có hai phiên bản ddresTHER có thể nằm trong kho của bạn: xem câu hỏi về vấn đề này để biết thêm thông tin. Phiên bản bạn muốn là GNU ddresTHER và trên các hệ thống dựa trên Debian là gói có tên gddrescue:

sudo apt install gddrescue

Đối với các bản phân phối khác, hãy kiểm tra hệ thống quản lý gói của bạn để biết phiên bản GNU của ddresTHER.


1
Vì lợi ích của người dùng mới: ddresTHER là một công cụ GNU, nhưng nó có thể không tồn tại trên Linux, Mac hoặc hệ thống giống như unix khác của bạn. ddresTHER không xuất hiện theo yêu cầu của POSIX hoặc bất kỳ tiêu chuẩn nào khác.

2

Giải pháp khác:

cat file1 | tee -a file2

tee có lợi ích mà bạn có thể thêm vào bao nhiêu tệp tùy thích, ví dụ:

cat file1 | tee -a file2 file3 file3

sẽ nối các nội dung của file1để file2, file3file4.

Từ trang người đàn ông:

-a, --append
       append to the given FILEs, do not overwrite

0

catcó thể là giải pháp dễ dàng nhưng điều đó trở nên rất chậm khi chúng tôi ghép các tệp lớn, find -printlà để giải cứu bạn, mặc dù bạn phải sử dụng mèo một lần.

amey@xps ~/work/python/tmp $ ls -lhtr
total 969M
-rw-r--r-- 1 amey amey 485M May 24 23:54 bigFile2.txt
-rw-r--r-- 1 amey amey 485M May 24 23:55 bigFile1.txt

 amey@xps ~/work/python/tmp $ time cat bigFile1.txt bigFile2.txt >> out.txt

real    0m3.084s
user    0m0.012s
sys     0m2.308s


amey@xps ~/work/python/tmp $ time find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1

real    0m2.516s
user    0m0.028s
sys     0m2.204s

Tiết kiệm thời gian bạn báo cáo cho lệnh kết hợp find / cat của bạn là bởi vì bạn chỉ định thời gian cho lệnh find chỉ in ra tên của các tệp. Hãy thử định thời gian cho toàn bộ lệnh như thế này: time (find . -maxdepth 1 -type f -name 'bigFile*' -print0 | xargs -0 cat -- > outFile1)và nó sẽ tạo ra kết quả tương tự với lệnh chỉ con mèo của bạn.
JoshMc

0

Bạn cũng có thể làm điều này mà không cần cat, mặc dù trung thực catlà dễ đọc hơn:

>> file1 < file2

Việc >>nối STDIN vào file1và kết <xuất file2thành STDIN .



@ user202729 Bạn nói đúng, nó không hoạt động trong bash. Nó không hoạt động trong zsh.
Alok Singh
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.