Câu trả lời:
Nó không hoạt động vì catchương trình trong chuỗi ống của bạn không được hướng dẫn để đọc echođầu ra của chương trình từ đầu vào tiêu chuẩn.
Bạn có thể sử dụng -làm tên tệp giả để chỉ ra đầu vào tiêu chuẩn cat. Từ man catcài đặt msys2:
EXAMPLES
cat f - g
Output f's contents, then standard input, then g's contents.
Hãy thử
echo "abc" | cat - 1.txt > 2.txt
thay thế.
Như đã lưu ý bởi những người khác, lệnh ban đầu của bạn không thành công vì cat 1.txtbỏ qua đầu vào tiêu chuẩn của nó. Hoặc chỉ ra rằng nó phải là đối số đầu tiên của nó ( cat - 1.txt) hoặc sử dụng chuyển hướng khối để chuyển hướng echo abc và cat 1.txt cùng nhau. Để dí dỏm:
{ echo abc; cat 1.txt; } > 2.txt
Đoạn trích liên quan từ hướng dẫn ( man bash):
Lệnh Compound Lệnh
ghép là một trong những lệnh sau. Trong hầu hết các trường hợp, một danh sách trong mô tả của lệnh có thể được tách biệt với phần còn lại của lệnh bằng một hoặc nhiều dòng mới và có thể được theo sau bởi một dòng mới thay cho dấu chấm phẩy.
(danh sách)danh sách được thực thi trong môi trường mạng con (xem MÔI TRƯỜNG THỰC HIỆN QUY TẮC bên dưới). Các phép gán biến và các lệnh dựng sẵn ảnh hưởng đến môi trường của shell không còn hiệu lực sau khi lệnh hoàn thành. Trạng thái trả về là trạng thái thoát của danh sách.
{danh sách;}danh sách được thực hiện đơn giản trong môi trường shell hiện tại. danh sách phải được chấm dứt bằng một dòng mới hoặc dấu chấm phẩy. Điều này được gọi là một lệnh nhóm . Trạng thái trả về là trạng thái thoát của danh sách . Lưu ý rằng không giống như các ký tự đại diện
(và),{và}là các từ dành riêng và phải xảy ra khi một từ dành riêng được phép được công nhận. Vì chúng không gây ra ngắt từ, chúng phải được tách ra khỏi danh sách bằng khoảng trắng hoặc metacharacter vỏ khác.
Tùy chọn đầu tiên (môi trường subshell) có một loạt các tác dụng phụ, hầu hết nếu không phải tất cả đều không liên quan đến kịch bản của bạn; tuy nhiên, nếu chuyển hướng một loạt các đầu ra của lệnh là tất cả những gì bạn cần, thì Tùy chọn # 2 ở đây (lệnh nhóm) được ưu tiên.
( echo "abc"; cat 1.txt ) > 2.txt
Bạn đã chuyển đầu ra echo thành cat, nhưng cat không sử dụng được đầu vào và bỏ qua nó. Bây giờ các lệnh chạy lần lượt từng cái và đầu ra của chúng được nhóm lại (dấu ngoặc đơn) và được hướng vào 2.txt.
bash(1), nó mô tả hành vi mà mọi vỏ tuân thủ POSIX phải hỗ trợ.
Trong bất kỳ shell POSIX nào, bạn có thể sử dụng thay thế lệnh để sử dụng cat filelàm đầu vào cho echo:
echo $(cat file1.txt) "This Too"
Trong Bash, bạn có thể sử dụng thay thế quá trình và sử dụng echo như một "tệp" khác cat, như trong:
cat file1.txt <(echo This Too)
và sau đó ống hoặc chuyển hướng đầu ra khi bạn thấy phù hợp.
Giống như mọi câu trả lời khác, mèo bỏ qua stdin nếu nó có một tập tin để xem. (Tôi cũng thích câu trả lời của Daniel & mvw, +1 cho họ)
<(command)xây dựng là một phần mở rộng bash. Nó không phải là POSIX, vì vậy bạn không thể dựa vào nó trong các tập lệnh được cho là được thực thi /bin/sh.
Chỉ là một phỏng đoán, nhưng có vẻ như bạn có một quy trình lặp lại, đó là một ứng cử viên tốt cho bí danh hoặc chức năng. Các bí danh thường là các đoạn cắt ngắn để gọi các lệnh bash, chẳng hạn như viết tắt, trên một luồng đầu vào dưới dạng đối số / s của nó.
alias hg="history | grep"
Tuy nhiên, trong trường hợp này, một hàm sẽ dễ đọc hơn, vì bạn đang kết hợp nhiều luồng đầu vào, 2 (rời rạc) cũng như nhiều lệnh bash. Bạn có hai đối số, đầu tiên là một chuỗi và bên kia là một filepath. Cuối cùng, bạn muốn kết quả được ghi vào luồng đầu ra xuất chuẩn.
Từ một dấu nhắc CLI, gõ này:
# ecat()
{
echo ${1}
cat ${2}
}
Chức năng của bạn được đặt tên là ecat, đó là đáng nhớ.
Bây giờ bạn có thể gọi như
ecat "abc" 1.txt
Để nối thêm, chỉ cần cung cấp đích đầu ra khác cho thiết bị xuất chuẩn:
ecat "abc" 1.txt >> 2.txt
Toán tử chuyển hướng chắp thêm '>>' sẽ thêm đầu ra vào cuối tệp được chỉ định.
Nếu bạn thích nó, sau đó nối vào tệp ~ / .bashrc của bạn để sử dụng lại.
declare -f ecat >> ~/.bashrc
Điều đó cũng có nghĩa là bạn có thể trang trí, vv, trong định nghĩa chức năng của bạn.
Cũng là một ý tưởng tốt để bảo vệ các tệp khỏi bị ghi đè bằng cách thêm tệp này vào ~ / .bashrc của bạn
set noclobber
"$1"và "$2". Trong bối cảnh này, niềng răng xoăn không làm gì tốt. Xem ${name}không có nghĩa là những gì bạn nghĩ rằng nó làm .
noclobbergợi ý đáp ứng với câu hỏi trong tầm tay? (Tôi cũng không tin lắm rằng đó là lời khuyên tốt - sửa đổi hành vi toàn cầu có xu hướng phá vỡ các kịch bản / lời khuyên / thực tiễn được xây dựng với ý định mặc định).
Các mã sau đây cũng sẽ hoạt động:
echo abc >> 1.txt && cat 1.txt > 2.txt
Đầu ra của echo abc sẽ được thêm vào 1.txt với >> Sau đó, && sẽ bảo nó chạy bộ lệnh tiếp theo sẽ cat 1.txt và sau đó xuất thành 2.txt . Về cơ bản, nó nối đầu ra của lệnh đầu tiên vào 1.txt và sau đó gửi đầu ra của 1.txt thành 2.txt.
Nếu bạn muốn abc xuất hiện đầu tiên, bạn có thể sử dụng mã sau:
echo abc >> 2.txt && cat 1.txt >> 2.txt
abcở dưới cùng của 2.txt; câu hỏi muốn nó ở đầu (2) sửa đổi các 1.txttập tin; Điều này là không thể chấp nhận được.
echotrước cattrong lệnh mẫu, tôi giả sử rằng nó không bao giờ chính xác, rõ ràng , nói rằng họ muốn đầu ra từ tiếng vang trước nội dung của tập tin đầu vào. Có vẻ như hầu hết mọi người giải thích nó theo cách đó. (2) 1.txtlà một tập tin đầu vào. Câu hỏi không nói gì về sửa đổi 1.txt. Thực tế là các tập tin đầu vào không nên được sửa đổi mà không cần nói.
catchỉ đọc từ đầu vào tiêu chuẩn nếu chúng không có bất kỳ đối số tên tệp nào.