Chuyển hướng nội dung của tập tin sang lệnh


41

Tôi có một tập tin có tên my_file.txtnội dung chỉ là chuỗi Hello. Làm thế nào tôi có thể chuyển hướng nội dung của nó đến lệnh echo?

Tôi biết tôi có các lệnh less, cat, more... nhưng tôi cần phải làm điều đó với echo.

Tôi đã thử điều này:

$ cat my_file.txt | echo

và cũng thế này:

$ echo < my_file.txt

Nhưng trong cả hai trường hợp, nó chỉ xuất hiện một khoảng trống trong thiết bị xuất chuẩn, không phải nội dung của my_file.txt.

Làm thế nào tôi có thể làm điều đó?


7
Tại sao bạn khăng khăng sử dụng echo?
Kevin

7
@Kevin, có lẽ cuối cùng anh ta muốn mở rộng các chuỗi thoát ANSI C ( \n, b...) trong tệp, đây sẽ là cách sử dụng hợp lệ echo(ít nhất là một tiêu chuẩn echo). Hoặc có lẽ anh ta muốn hiểu tại sao nó không hoạt động theo cách đó. Trong mọi trường hợp, không có lý do để downvote IMO.
Stéphane Chazelas

3
Tôi đến đây vì tôi tò mò về lý do tại sao nó không hoạt động khi tôi thực hiện echo <file.txt. Có vẻ là một câu hỏi hợp lý để có tại SE, câu trả lời là rất hữu ích. +1 từ tôi.
nơron

Câu trả lời:


53

Bạn có thể chuyển hướng tất cả những gì bạn muốn echonhưng nó sẽ không làm gì với nó. echokhông đọc đầu vào tiêu chuẩn của nó. Tất cả những gì nó làm là ghi ra đầu ra tiêu chuẩn, các đối số của nó được phân tách bằng ký tự khoảng trắng và được chấm dứt bởi một ký tự dòng mới (và với một số echotriển khai với một số chuỗi thoát trong chúng được mở rộng và / hoặc các đối số bắt đầu có -thể được coi là tùy chọn).

Nếu bạn muốn echohiển thị nội dung của tệp, bạn phải chuyển nội dung đó làm đối số echo. Cái gì đó như:

echo "$(cat my_file.txt)"

Lưu ý rằng $(...)dải xuống dòng nhân vật dấu s từ đầu ra của mà catlệnh, và echothêm một trở lại.

Cũng lưu ý rằng ngoại trừ zsh, bạn không thể chuyển các ký tự NUL trong các đối số của lệnh, do đó, ở trên thường sẽ không hoạt động với các tệp nhị phân. yashcũng sẽ loại bỏ các byte không tạo thành một phần của các ký tự hợp lệ.

Nếu lý do muốn làm điều đó là bởi vì bạn muốn echođể mở rộng \n, \b, \0351... trình tự thoát trong file (như UNIX tuân thủ QTI echotriển khai làm, nhưng không phải tất cả ), sau đó bạn muốn sử dụng printfthay vì :

printf '%b\n' "$(cat my_file.txt)"

Trái ngược với echo, cái đó là di động và sẽ không gặp vấn đề gì nếu nội dung của tệp bắt đầu bằng -.


Thay thế cho $(cat file), với ksh, zshbash, người ta cũng có thể làm :$(<file) . Đó là một toán tử đặc biệt, theo đó shell thaycatđọc nội dung của tệp để tạo thành phần mở rộng. Nó vẫn loại bỏ các dòng mới và cuộn cảm trên các byte NUL ngoại trừ trong zsh. Trong bashđó, vẫn còn một quá trình thêm. Cũng lưu ý rằng một điểm khác biệt là bạn sẽ không gặp phải bất kỳ lỗi nào nếu cố đọc một tệp có loại thư mục theo cách đó. Ngoài ra, trong khi $(< file)đặc biệt, $(< file; other command)không (trong zshkhi không mô phỏng trình bao khác, nó vẫn sẽ mở rộng nội dung của file, bằng cách chạy lệnh ẩn $READNULLCMD (thường là máy nhắn tin)).


3
Trong cả bash và zsh, bạn có thể bỏ qua catvà chỉ cần đọc vỏ trực tiếp : echo "$(<my_file.txt)".
Kevin

1
Có, với ksh , zshbash bạn có thể sử dụng $(<filename).
Dimitre Radoulov

Cảm ơn bạn rất nhiều, đó là những gì tôi cần và nó đã làm việc! :-)
danielmbcn

@Kevin, Dimitre, đã thêm ngay bây giờ.
Stéphane Chazelas

4

Thêm vào các câu trả lời khác, bạn cũng có thể thử chuyển hướng đầu vào thay vì cat

echo $(<my_file.txt)

hoặc là

echo `<my_file.txt`

$()và `` thực hiện cùng một thứ, chúng chạy các lệnh bên trong phạm vi của chúng và đưa đầu ra cho shell như thể nó được đưa ra như một đầu vào của người dùng. Sự khác biệt duy nhất giữa hai điều này là $ () có thể được đệ quy và `` không thể được đệ quy.


2

Câu trả lời đơn giản: bạn không thể. echo(có thể là vỏ được tích hợp sẵn hoặc nhị phân thông thường) không xử lý đầu vào tiêu chuẩn của nó - đó chỉ là một cách.


Câu hỏi là, tại sao bạn thực sự muốn làm điều này?
peterph

2

Như đã nói,

Nếu bạn muốn echohiển thị nội dung của tệp, bạn phải chuyển nội dung đó làm đối số choecho

Chẳng hạn, bạn có thể làm như thế này với xargs(xem xét rằng bạn cần kích hoạt giải thích các dấu gạch chéo ngược ):

$ cat my_file.txt | xargs echo -e

Hoặc đơn giản là những gì bạn đã hỏi (giải thích về các chuỗi thoát ):

$ cat my_file.txt | xargs echo

Tuy nhiên, lưu ý rằng khi sử dụng xargs echo(giống như xargsbtw như echolà lệnh mặc định), đó là echolệnh từ hệ thống tệp sẽ được chạy, chứ không phải echolệnh dựng sẵn của shell . Cũng lưu ý rằng xargsmong đợi đầu vào của nó trong một định dạng rất cụ thể (trong đó khoảng trắng, dòng mới, dấu ngoặc kép, dấu gạch chéo ngược có ý nghĩa đặc biệt). catkhông có ý nghĩa nhiều như ở đây chỉ có một tập tin để concatenate (giống như < file.txt xargs echoLưu ý rằng Unix tuân thủ. echos làm xuyệc ngược bành trướng thoát theo mặc định và đầu ra -ethuận echo -e.
Stéphane Chazelas

0

Trong bash, cũng nên làm như sau:

echo `cat my_file.txt`

Phần trong backticks được thay thế bằng đầu ra của lệnh đó, tức là trong trường hợp này được thay thế bằng nội dung tệp.


Đúng, backticks làm việc như thế nào $( . . . ). Những người sử dụng $()thường thích chúng vì bạn có thể lồng chúng. Câu hỏi này đã cũ, tuy nhiên, nó thỏa mãn hơn nhiều khi trả lời những câu hỏi chưa được trả lời!
Luật29

Không hẳn. Có một sự khác biệt tinh tế. Khi biểu mẫu back-tick được sử dụng, dấu gạch chéo ngược vẫn giữ nguyên nghĩa đen của nó trừ khi được theo sau bởi $, `hoặc \. Dấu kiểm ngược đầu tiên không có trước dấu gạch chéo ngược chấm dứt lệnh. Khi sử dụng biểu mẫu $ (,,,), tất cả các ký tự giữa các dấu ngoặc đơn tạo thành lệnh.
fpmurphy

Vì sự thay thế lệnh đó không được trích dẫn, toán tử split + global sẽ được áp dụng cho nó. Ví dụ, nếu my_file.txtchứa *, điều đó sẽ in danh sách tên tệp trong thư mục hiện tại.
Stéphane Chazelas
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.