Một chương trình có thể đệm stdin hoặc tập tin


12

Ngoài việc sử dụng một tệp tạm thời để trợ giúp, có một cách / chương trình có thể đệm đầu vào từ stdinnhưng không xuất nội dung cho đến khi nhận được EOF. Tôi cũng không muốn sử dụng biến shell (ví dụ buffer=$(cat)).

Chương trình này sẽ hoạt động như dưới đây (giả sử tên chương trình là buffered-cat):

$ buffered-cat
line 1
line 2
line 3
^D # Ctr-D here(End of Line)

Bây giờ chương trình đã nhận được ^D, buffered-catđầu ra nội dung

line 1
line 2
line 3

Tôi thường sử dụng sortcho mục đích này. Rõ ràng nó có tác dụng phụ có thể không mong muốn.
Adrian Pronk

Câu trả lời:


20

Một người đàn ông nghèo đang spongesử dụng awk:

awk '{a[NR] = $0} END {for (i = 1; i <= NR; i++) print a[i]}'

Nếu bạn có tac, bạn cũng có thể sử dụng sai:

... | tac | tac

1
taclà đơn giản và thanh lịch, tôi nghĩ.
Ekeyme Mo

6
@EkeymeMo | tac | tac rất đơn giản, nhưng hãy nhớ rằng nó rất kém hiệu quả cho nhiệm vụ và bạn sẽ phải chịu một cú đánh hiệu suất, đặc biệt là đối với các tệp lớn hơn.
Chấn thương kỹ thuật số

@DigitalTrauma yeah, tôi biết nhược điểm của điều đó. Tôi kiểm tra một tập tin với 100 nghìn dòng. Nó ổn với tôi. Tôi đã bình chọn lên nhận xét của bạn vì nó là sự thật.
Ekeyme Mo

29

Bạn có thể làm điều này với spongetừ moreutils . spongesẽ "ngâm đầu vào tiêu chuẩn và ghi vào một tập tin". Không có đối số, tập tin đó là đầu ra tiêu chuẩn. Đầu vào được cung cấp cho lệnh này được lưu trữ trong bộ nhớ cho đến EOF, và sau đó viết ra tất cả cùng một lúc.

Để ghi vào một tệp bình thường, bạn chỉ cần đặt tên tệp:

cmd | sponge filename

Mục đích chính spongelà cho phép đọc và ghi từ cùng một tệp trong một đường ống, nhưng nó cũng làm những gì bạn muốn.


6

Miễn là đầu vào của bạn là văn bản ASCII (không chứa byte NUL 0x0 cho đến hết), thì sed -zbạn sẽ làm những gì bạn muốn:

$ sed -z ''
Line 1
Line 2
Line 3
^D
Line 1
Line 2
Line 3
$ 

Các -znguyên nhân sedđể coi byte NUL là một dấu phân cách dòng thay vì dòng mới thông thường. Vì vậy, miễn là đầu vào của bạn là văn bản thông thường không có byte NUL, thì sed sẽ tiếp tục đọc toàn bộ đầu vào vào bộ đệm mẫu cho đến khi đạt được EOF. sedsau đó không xử lý trên bộ đệm và xuất ra nó.


Nếu byte NUL có trong đầu vào của bạn, thì bạn có thể làm điều này thay vào đó:

sed ':l;N;bl'


1

Hành vi bạn đang yêu cầu, đó không phải là hành vi mặc định của con mèo đơn giản sao?

gv@debian:$ cat << EOF #or cat <<EOF >file or cat <<EOF >/dev/stdout
> Line 1
> Line 2
> Line 3
> EOF
Line 1
Line 2
Line 3
gv@debian:$

3
Không, đó là hành vi của các tài liệu ở đây. Hãy thử gõ cat(Enter) Line 1(Enter) và xem điều gì sẽ xảy ra.
G-Man nói 'Phục hồi Monica'

Đúng, đó là cấu trúc tài liệu. Đơn giản và khá gần với những gì OP muốn. Không yêu cầu cài đặt
Sergiy Kolodyazhnyy

1

Ý tưởng tương tự như ví dụ awk của muru, ngoại trừ trong Python. Sử dụng CtrlDđể dừng đọc trong dòng

$ python -c 'import sys;print("".join(sys.stdin.readlines()))'                                                           
line1
line2
line3 # press Enter and Ctrl+D at this point
line1
line2
line3

2
Hoặc perl -e 'print <>'(!)
dave_thndry_085
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.