Câu hỏi Làm thế nào để nối stdin và một chuỗi?


Làm thế nào để tôi nối stdin vào một chuỗi, như thế này?

echo "input" | COMMAND "string"

và lấy

inputstring

76
2017-12-14 18:12


gốc




Các câu trả lời:


Một chút hacky, nhưng điều này có thể là cách ngắn nhất để làm những gì bạn hỏi trong câu hỏi (sử dụng một đường ống để chấp nhận stdout từ echo "input" như stdin cho một tiến trình / lệnh khác:

echo "input" | awk '{print $1"string"}'

Đầu ra:

inputstring

Bạn đang cố gắng thực hiện nhiệm vụ nào? Nhiều ngữ cảnh hơn có thể giúp bạn có thêm hướng đi trên một giải pháp tốt hơn.

Cập nhật - trả lời nhận xét:

@NoamRoss

Cách thành ngữ hơn để làm những gì bạn muốn là:

echo 'http://dx.doi.org/'"$(pbpaste)"

Các $(...) cú pháp được gọi là thay thế lệnh. Tóm lại, nó thực hiện các lệnh được bao bọc trong một vỏ mới, và thay thế stdout đầu ra đến nơi $(...) được gọi trong shell cha. Vì vậy, bạn sẽ nhận được, có hiệu lực:

echo 'http://dx.doi.org/'"rsif.2012.0125"

82
2017-12-14 18:24



Cảm ơn! Điều này làm việc tuyệt vời. Nhiệm vụ chính xác mà tôi đang cố gắng thực hiện là lấy một chuỗi từ clipboard (một DOI) và thêm một URL vào nó, vì vậy với điều này tôi làm pbpaste | awk '{print "http://dx.doi.org/"$1}'và lấy http://dx.doi.org/10.1098/rsif.2012.0125 - Noam Ross
@NoamRoss cập nhật câu trả lời; dường như chỉnh sửa;) - sampson-chen
@ sampson-chen, tôi sẽ sử dụng '{print $0"string"}' để nắm lấy toàn bộ sự việc. - Roman Newaza
Nó thực sự phụ thêm string cho mỗi dòng. Thử echo 'input'\n'another line' | awk '{print $0"string"}'. - tomekwi


sử dụng cat - để đọc từ stdin và đặt nó vào $() vứt bỏ dòng mới

echo input | COMMAND "$(cat -)string"

Tuy nhiên tại sao bạn không thả ống và lấy đầu ra của phía bên trái trong một lệnh thay thế:

COMMAND "$(echo input)string"

40
2017-12-14 20:51



Đây là ví dụ thực tế: tìm ~ / other_program / lib -name "* .jar" | tr '\ n' ':' | echo "$ (cat -) ~ / java_app / classes" - Ashwin Jayaprakash
Điều này làm việc cho tôi trong bash, nhưng trong zsh tôi nhận được "con mèo: -: Lỗi đầu vào / đầu ra". có ai biết cái gì làm ra thế này không? - jaymmer


Tôi thường sử dụng đường ống, vì vậy đây có xu hướng là một cách dễ dàng để tiền tố và hậu tố stdin:

echo "my standard in" | cat <(echo "prefix... ") <(cat -) <(echo " ...suffix")
prefix... my standard in ...suffix

21
2017-10-15 03:04



Cảm ơn! Đó là ví dụ thực sự rất thú vị khi sử dụng pipe và cat - Alex Ivasyuv
Đây sẽ là câu trả lời hay nhất - Chris Koston
Tại sao không chỉ: echo "my standard in" | echo -e "prefix\n$(cat -)\nsuffix"? Hoặc, phiên bản dễ đọc hơn: echo "my standard in" | printf "%s\n%s\n%s\n" "prefix" "$(cat -)" "suffix" - MiniMax
@MiniMax Bởi vì câu trả lời hoạt động tốt với các luồng, nó sẽ làm việc cho stdin lớn. - anishpatel
@anishpatel Phiên bản của tôi sẽ làm việc cho stdin lớn quá. Không khác nhau. - MiniMax


Bạn có thể làm điều đó với sed:

seq 5 | sed '$a\6'
seq 5 | sed '$ s/.*/\0 6/'

Trong ví dụ của bạn:

echo input | sed 's/.*/\0string/'

9
2018-02-15 08:29





Có một số cách để thực hiện điều này, cá nhân tôi nghĩ rằng tốt nhất là:

echo input | while read line; do echo $line string; done

Khác có thể bằng cách thay thế "$" (cuối dòng ký tự) bằng "chuỗi" trong lệnh sed:

echo input | sed "s/$/ string/g"

Tại sao tôi thích cái cũ hơn? Bởi vì nó nối một chuỗi thành stdin ngay lập tức, ví dụ với lệnh sau:

(echo input_one ;sleep 5; echo input_two ) | while read line; do echo $line string; done

bạn nhận được ngay lập tức đầu ra đầu tiên:

input_one string

và sau 5 giây bạn nhận được tiếng vọng khác:

input_two string

Mặt khác, sử dụng "sed" đầu tiên nó thực hiện tất cả nội dung của dấu ngoặc đơn và sau đó nó cho nó "sed", do đó, lệnh

(echo input_one ;sleep 5; echo input_two ) | sed "s/$/ string/g"

sẽ xuất cả hai dòng

input_one string
input_two string

sau 5 giây.

Điều này có thể rất hữu ích trong trường hợp bạn đang thực hiện các cuộc gọi đến các hàm cần một thời gian dài để hoàn thành và muốn được cập nhật liên tục về đầu ra của hàm.


8
2017-12-05 12:05



Trên thực tế, quyến rũ tùy chọn cũng xử lý mọi dòng đầu vào ngay lập tức. - tomekwi


Tôi biết đây là một vài năm muộn, nhưng bạn có thể thực hiện điều này với tùy chọn xargs -J:

echo "input" | xargs -J "%" echo "%" "string"

Và vì nó  xargs, bạn có thể làm điều này trên nhiều dòng của một tập tin cùng một lúc. Nếu tệp 'tên' có ba dòng, như:

Adam
Bob
Charlie

Bạn có thể làm:

cat names | xargs -n 1 -J "%" echo "I like" "%" "because he is nice"

4
2017-09-29 15:50



Có vẻ thú vị ngoại trừ -J dường như không phải là tiêu chuẩn / phổ biến. Trên Linux (ở đâu xargs là một phần của GNU findutils) Tôi gặp lỗi: xargs: invalid option -- 'J' Hệ thống này là gì? - arielf
-J dành cho phiên bản Mac. Dành cho Linux -I thực hiện cùng chức năng. - user2635263
Cảm ơn! rất hữu dụng. Xin lưu ý rằng trên Linux, phiên bản đơn giản này cũng hoạt động tốt: cat names | xargs -I% echo "I like % because he is nice" IOW: không cần cho -n 1 (xargs cuộc gọi echo một lần trên mỗi dòng đầu vào, kể từ đó -I ngụ ý -L1Ngoài ra, tất cả các trích dẫn arg riêng biệt, có vẻ là dư thừa. - arielf


Lệnh bạn đăng sẽ lấy chuỗi "đầu vào" sử dụng nó như dòng stdin của COMMAND, sẽ không tạo ra kết quả mà bạn đang tìm kiếm trừ khi COMMAND lần đầu in ra nội dung của stdin của nó và in ra các đối số dòng lệnh của nó.

Nó có vẻ như những gì bạn muốn làm là gần gũi hơn với thay thế lệnh.

http://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html#Command-Substitution

Với lệnh thay thế, bạn có thể có một dòng lệnh như thế này:

echo input `COMMAND "string"`

Điều này trước tiên sẽ đánh giá COMMAND bằng "chuỗi" làm đầu vào và sau đó mở rộng kết quả của việc thực thi lệnh đó lên một dòng, thay thế các ký tự '`'.


3
2017-12-14 18:23



và dĩ nhiên là @NaomRoss, trừ khi bạn được yêu cầu sử dụng Bourne shell hoặc có các nhiệm vụ "portability" điên khùng khác, bạn sẽ sử dụng lệnh thay thế hiện đại như echo input $(COMMAND "string"), thay vì backticks. Chúc mọi người may mắn. - shellter