Làm cách nào để sao chép nội dung của mỗi tệp trong danh sách sang tệp khác?


15

Tôi có một danh sách tên tệp trong một tệp được gọi list_of_files.txt.

Tôi muốn sao chép nội dung của từng tệp trong danh sách đó vào một tệp khác được gọi all_compounds.sdf.

Làm thế nào tôi nên làm điều này từ dòng lệnh?

Câu trả lời:


20

Không sử dụng thay thế lệnh đơn giản để có được tên tệp (có thể dễ dàng phá vỡ bằng khoảng trắng và các ký tự đặc biệt khác). Sử dụng một cái gì đó như xargs:

xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf

Hoặc một while readvòng lặp:

while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf

Để sử dụng thay thế lệnh một cách an toàn, ít nhất hãy đặt thành IFSdòng mới và vô hiệu hóa toàn cầu hóa (mở rộng ký tự đại diện):

(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)

Các dấu ngoặc đơn xung quanh ()sẽ chạy cái này trong một khung con, để lớp vỏ hiện tại của bạn không bị ảnh hưởng bởi những thay đổi này.


14

Cách nhanh và bẩn ...

cat $(cat list_of_files.txt) >> all_compounds.sdf

Xin lưu ý: điều này chỉ hoạt động nếu tên tệp trong danh sách của bạn được xử lý rất tốt - mọi thứ sẽ sai nếu chúng có khoảng trắng, dòng mới hoặc bất kỳ ký tự nào có ý nghĩa đặc biệt với vỏ - thay vào đó hãy sử dụng câu trả lời này để có kết quả đáng tin cậy)

Ghi chú

  • catcon mèo enate tập tin. Nó cũng in nội dung của họ.
  • Sử dụng thay thế lệnh, command2 $(command1)bạn có thể chuyển đầu ra của command1( cat list...) đến command2( cat) để nối các tệp.
  • Sau đó sử dụng chuyển hướng >>để gửi đầu ra đến một tệp thay vì in ra thiết bị xuất chuẩn. Nếu bạn muốn xem đầu ra, sử dụng teethay thế:

    cat $(cat list_of_files.txt) | tee -a all_compounds.sdf

(Tôi đã sử dụng >>thay vì >teevới công -atắc trong trường hợp tệp của bạn đã tồn tại - phần này sẽ thêm vào tệp thay vì ghi đè lên nó, nếu nó đã tồn tại)


1
@Zanna trích dẫn các thay thế lệnh để tránh chia tách từ, như"$(cat list_of_files.txt)"
Sergiy Kolodyazhnyy

4
@Serg nếu tách từ không được thực hiện, sau đó catlấy toàn bộ danh sách làm một đối số.
muru

@muru OK, làm thế nào để chúng ta đối phó với tên tệp có chứa khoảng trắng?
Sergiy Kolodyazhnyy

1
@Serg đặt IFS tương ứng - xem đoạn cuối câu trả lời của tôi
muru

4

Trong khi GNU awklà một tiện ích xử lý văn bản, nó cho phép chạy các lệnh shell bên ngoài thông qua system()cuộc gọi. Chúng ta có thể tận dụng điều đó cho lợi thế của mình như vậy:

$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        

Ý tưởng ở đây rất đơn giản: chúng tôi đọc từng dòng tệp và trong mỗi dòng chúng tôi tạo ra chuỗi được định dạng cat "File name.txt", sau đó được chuyển đến system().

Và đây là hành động:

$ ls
file1.txt  file2.txt  file3 with space.txt  file_list.txt


$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        
Hi, I'm file2
Hi, I'm file1
Hi, I'm file3

Vì vậy, chúng tôi đã hoàn thành phần lớn nhiệm vụ ở đó - chúng tôi đã in tất cả các tệp trong danh sách. Phần còn lại rất đơn giản: chuyển hướng đầu ra cuối cùng sang tệp với >toán tử vào tệp tóm tắt.

awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
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.