xuất ra tệp, sau đó sử dụng tệp cho đầu vào


7

Có một cách viết ngắn hơn này? Về cơ bản xuất lệnh cho một tệp, sau đó sử dụng tệp làm đầu vào cho lệnh tiếp theo. Tôi cũng muốn giữ tập tin để xem sau đó.

cmd1 > verylong.txt; cmd2 < verylong.txt

Tôi biết tôi có thể làm

cmd1 | tee verylong.txt | cmd2

Nhưng vì tôi hy vọng "Verylong.txt" sẽ là một tệp khổng lồ, tôi nghĩ rằng việc sử dụng ống sẽ kém hiệu quả hơn vì nó sẽ giữ toàn bộ tệp trong bộ nhớ. Trong khi đó, nếu tôi sử dụng tập tin đầu vào thì nó sẽ xử lý từng dòng một. (Hay giả định của tôi sai?)

Sẽ thật tuyệt nếu tôi có thể làm một cái gì đó thanh lịch như

cmd1 > verylong.txt > cmd2

Câu trả lời:


15

Theo tôi biết, cmd1 | tee verylong.txt | cmd2sẽ không giữ toàn bộ tập tin trong bộ nhớ. Trong thực tế, nếu cmd2phải chờ quá lâu trước khi sử dụng đầu vào của nó, cmd1có thể chặn writecuộc gọi và chỉ bỏ chặn khi cmd2bắt đầu đọc lại.

Lý do cho điều đó là có một bộ đệm cho đường ống và bộ đệm đó, theo mặc định, được giới hạn ở một kích thước hợp lý nhất định .

Tất nhiên, câu chuyện có thể khác nếu cmd2sort(hoặc một cái gì đó giống nhau) trong đó toàn bộ đầu vào phải được đọc trước khi lệnh có thể ghi đầu ra của nó. Trong trường hợp đó, toàn bộ nội dung tệp có thể được giữ trong cmd2bộ nhớ, nhưng điều đó không phụ thuộc vào việc một đường ống hoặc tệp trung gian được sử dụng cho đầu vào của lệnh đó.


3
sortkhông lưu trữ toàn bộ tệp trong bộ nhớ, nó cũng có bộ đệm với kích thước tối đa và sử dụng các tệp tạm thời khi đạt đến mức tối đa đó.
Stéphane Chazelas

@ StéphaneChazelas Rất tốt để biết, có một upvote! ;) Tôi sẽ cập nhật câu trả lời để ít quyết đoán hơn trong phần "giữ vào bộ nhớ".
user43791

6

Câu trả lời đã được đưa ra là chính xác. Nhưng nếu mục tiêu của bạn là chọn lọc đọc verylongfile.txtw / cmd2, sedcó thể là một lựa chọn khác.

cmd1 | sed -e 'w verylongfile.txt' -e '/notinteresting/d' | cmd2

sedsẽ wnghi thức tất cả các đầu vào của nó tới outfile, nhưng chỉ các bit không khớp với /notinteresting/địa chỉ với đường ống. Hoặc bạn có thể phủ nhận hành động /interesting/!dsẽ chỉ viết các dòng khớp với interestingđịa chỉ với đường ống.

Tuy nhiên, nếu đây không phải là mục tiêu của bạn, hãy sử dụng tee- đó là một công cụ hiệu quả hơn để ghi toàn bộ dữ liệu đầu vào của nó vào cả outfile và pipe.


0

Có một mẹo thông minh với tee và subshells:

cat source.lst | tee >(doSomething.sh) >(somethingElse.sh) | somethingFinal.sh

Tôi đã làm điều này trước đây

pv -perl source.list | tee >(doSomething.sh) >(somethingElse.sh) | md5sum

pvsẽ cung cấp cho bạn một thanh tiến trình, ETA và tổng số dòng đang chạy. Sau đó, source.lst sẽ được cung cấp cho doS Something.sh và SomethingElse.sh (và trên các CPU khác nhau!) Cuối cùng, chúng tôi sẽ nhận được một md5sum của ôm đó, chỉ cho mục đích học tập.


-5

Có gì sai với tập tin lô hai dòng đơn giản? Giống:

Cmd1 >filespec
Cmd2 <filespec

Hoặc là

cmd1 >filespec
cmd2 filespec

một trong hai cách, tập tin được để lại trong bộ lưu trữ lớn.


Vì một số lý do, trang web không cho phép tôi nhập vào một biểu tượng nhỏ hơn. và thả phần thứ hai của cmd2. Vì vậy, trong các từ cmd1 chuyển hướng ra tập tin. dòng tiếp theo cmd2 chuyển hướng từ tập tin. HOẶC cho cmd2, chỉ cần đặt tên tệp làm tham số đầu tiên và cmd2 chỉ cần mở tệp.
dùng92319

Bạn sử dụng &lt;cho <biểu tượng ...
jasonwryan

1
Một điểm khác biệt giữa cmd | tee file | cmdcmd >file; cmd <filelà các lệnh trong nhóm đầu tiên được thực thi song song - nghĩa là tất cả chúng đều bắt đầu cùng một lúc. Và do đó, cmd2có thể xử lý cmd1đầu ra của nó khi nó được viết, trong khi đó cmd1; cmd2là hai lệnh được thực thi lần lượt - hoặc nói cách khác, cmd2phải chờ cmd1để hoàn thành trước khi xử lý bất cứ điều gì.
mikeerv

Tác giả của câu hỏi đặc biệt yêu cầu một lệnh khác với lệnh đó vì các tệp rất lớn. Thực hiện các tệp bằng phương pháp của bạn sẽ chậm hơn rất nhiều so với cmd1 | tệp tee | cmd2.
Đánh dấu
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.