Làm thế nào để nối stdin và một chuỗi?


108

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

echo "input" | COMMAND "string"

và lấy

inputstring

Câu trả lời:


119

Hơi khó hiểu, nhưng đây có thể là cách ngắn nhất để thực hiện những gì bạn đã hỏi trong câu hỏi (sử dụng một đường ống để chấp nhận stdouttừ echo "input"như stdinđến một quy trình / lệnh khác:

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

Đầu ra:

inputstring

Chính xác bạn đang cố gắng hoàn thành nhiệm vụ gì? Nhiều ngữ cảnh hơn có thể giúp bạn có thêm định hướng về một giải pháp tốt hơn.

Cập nhật - trả lời bình luận:

@NoamRoss

Sau đó, 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 thay thế lệnh . Nói tóm lại, nó thực thi các lệnh được bao bọc trong một vỏ thay thế mới và thay thế stdoutđầu ra của nó vào nơi mà lệnh $(...)được gọi trong vỏ mẹ. Vì vậy, bạn sẽ nhận được, trong thực tế:

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

1
Cảm ơn! Điều này hoạt động tuyệt vời. Nhiệm vụ chính xác tôi đang cố gắng để thực hiện là để có một chuỗi từ clipboard (một DOI) và thêm vào trước URL để nó, vì vậy với điều này tôi làm pbpaste | awk '{print "http://dx.doi.org/"$1}'và nhận đượchttp://dx.doi.org/10.1098/rsif.2012.0125
Noam Ross

5
@ sampson-chen, tôi muốn '{print $0"string"}'lấy toàn bộ.
Roman Newaza

3
Nó thực sự dính stringvào mọi dòng. Cố gắng echo 'input'\n'another line' | awk '{print $0"string"}'.
tomekwi

55

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

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

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

COMMAND "$(echo input)string"

1
Đây là một ví dụ thực tế: find ~ / other_program / lib -name "* .jar" | tr '\ n' ':' | echo "$ (cat -) ~ / java_app / class"
Ashwin Jayaprakash

2
Điều này hoạt động đối với tôi trong bash, nhưng trong zsh tôi nhận được "cat: -: Lỗi đầu vào / đầu ra". có ai biết cái gì làm ra thế này không?
jaymmer - Khôi phục Monica

"COMMAND" là viết tắt của giải pháp và "đầu vào tiếng vọng" cho một số quy trình phức tạp hơn. Đối số "-" đối với mèo chỉ được yêu cầu nếu có các nhóm tệp khác, nếu không nó là mặc định. Ý bạn là: đầu vào tiếng vang | chuỗi echo $ (cat)
Denis Howe

46

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

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

2
Cảm ơn! Đó là thực sự rất mát dụ của việc sử dụng pipecat
Alex Ivasyuv

1
Đây phải là câu trả lời tốt nhất
Chris Koston

1
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

1
@MiniMax Vì câu trả lời hoạt động tốt với các luồng nên nó sẽ hoạt động đối với stdin lớn.
anishpatel

1
@anishpatel Phiên bản của tôi cũng sẽ hoạt động cho stdin lớn. Không khác nhau.
MiniMax

11

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

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

Một cách khác có thể bằng cách thay thế "$" (ký tự cuối dòng) bằng "string" trong một 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 với 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 ngay lập tức nhận đượ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, việc sử dụng "sed" trước tiên nó thực hiện tất cả nội dung của dấu ngoặc và sau đó nó đưa nó cho "sed", vì vậy lệnh

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

sẽ xuất ra 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 lệnh gọi đến các hàm mất nhiều thời gian để hoàn thành và muốn được cập nhật liên tục về đầu ra của hàm.


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

Đối với một dòng đầu vào, giải pháp đơn giản nhất là đầu vào echo | (read v; echo $ {v} string) Đó là shell thuần túy nên không yêu cầu quá trình bổ sung như sed.
Denis Howe

7

Tôi biết điều này là muộn vài năm, 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ể thực hiện việc này trên nhiều dòng của tệp 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"

1
Trông bắt mắt ngoại trừ -Jdường như không phải là tiêu chuẩn / phổ biến. Trên Linux (ở đâu xargslà một phần của GNU findutils) tôi gặp lỗi: xargs: invalid option -- 'J'Hệ thống này nằm trên hệ thống nào?
mình

3
-Jdành cho phiên bản Mac. Đối với Linux -Ithực hiện chức năng tương tự.
dùng2635263

1
Cảm ơn! rất hữu ích. 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 -n 1( dù sao cũng xargsgọi echomột lần cho mỗi dòng đầu vào, vì -Ingụ ý -L1) Ngoài ra, tất cả các trích dẫn đối số riêng biệt, dường như là thừa.
22/07/2016

3

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

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

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

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

echo input `COMMAND "string"`

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


và tất 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ụ "di động" điên rồ khác, bạn sẽ sử dụng thay thế lệnh hiện đại echo input $(COMMAND "string"), thay vì backticks. Chúc mọi người may mắn.
shellter 14/12/12

1

mèo sẽ là lựa chọn của tôi: ls | cat - <(echo new line)


sed là một căn cứ dòng lệnh mà không làm việc nếu ống thượng nguồn có đầu ra không có gì ..
clarkttfu

0

Cũng hoạt động:

seq -w 0 100 | xargs -I {} echo "string "{}

Sẽ tạo ra các chuỗi như:

string 000
string 001
string 002
string 003
string 004

...

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.