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?
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:
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 read
vò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 IFS
dò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.
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)
cat
con mèo enate tập tin. Nó cũng in nội dung của họ.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 tee
thay thế:
cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
(Tôi đã sử dụng >>
thay vì >
và tee
với công -a
tắ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)
cat
lấy toàn bộ danh sách làm một đối số.
Trong khi GNU awk
là 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
"$(cat list_of_files.txt)"