如何连接标准输入和字符串?


Answers:


119

有点哈克,但这可能是做你的问题(使用管道来接受询问的最短途径stdout,从echo "input"作为stdin另一个进程/命令:

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

输出:

inputstring

您到底要完成什么任务?更多上下文可以为您提供更好解决方案的更多指导。

更新-回应评论:

@NoamRoss

然后,更惯用的方式做您想要的事情:

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

$(...)语法称为命令替换。简而言之,它将执行包含在新子外壳程序中的命令,并将其stdout输出替换为$(...)在父外壳程序中调用的位置。因此,您将获得以下效果:

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

1
谢谢!这很好。我试图完成的具体任务是把从剪贴板(一DOI)的字符串,并在前面加上一个URL来,所以这个我做pbpaste | awk '{print "http://dx.doi.org/"$1}',让http://dx.doi.org/10.1098/rsif.2012.0125
诺姆·罗斯

5
@ sampson-chen,我通常会'{print $0"string"}'抓住整个东西。
罗曼·纽瓦萨

3
它实际上附加string到每一行。尝试echo 'input'\n'another line' | awk '{print $0"string"}'
tomekwi's

55

用于cat -从stdin读取,并放入其中$()以丢弃尾随的换行符

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

但是,为什么不放下管道并在命令替换中获取左侧的输出:

COMMAND "$(echo input)string"

1
这是一个实际的示例:查找〜/ other_program / lib -name“ * .jar” | tr'\ n'':'| echo“ $(cat-)〜/ java_app / classes”
Ashwin Jayaprakash

2
这在bash中对我有用,但是在zsh中我得到“ cat:-:输入/输出错误”。知道是什么原因造成的吗?
jaymmer-恢复莫妮卡

“ COMMAND”代表解决方案,“ echo input”代表更复杂的过程。仅当存在其他文件args时,才需要cat的“-” args,否则为默认值。所以你的意思是:回声输入| echo $(cat)string
Denis Howe,

46

我经常使用管道,因此这通常是为stdin加上前缀和后缀的简便方法:

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

2
谢谢!那实际上是使用pipeand的非常酷的例子cat
Alex Ivasyuv

1
这应该是最好的答案
克里斯·科斯顿

1
为什么不只是:echo "my standard in" | echo -e "prefix\n$(cat -)\nsuffix"?或者,更具可读性的版本:echo "my standard in" | printf "%s\n%s\n%s\n" "prefix" "$(cat -)" "suffix"
MiniMax

1
@MiniMax因为答案适用于流,所以适用于大型stdin。
anishpatel

1
@anishpatel我的版本也适用于大型stdin。没有不同。
MiniMax '10

11

您可以使用sed来做到这一点:

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

在您的示例中:

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

9

有一些方法可以做到这一点,我个人认为最好的是:

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

另一个方法是在sed命令中用“ string”替换“ $”(行尾字符):

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

为什么我更喜欢前者?因为它会立即将字符串连接到stdin,例如,使用以下命令:

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

您将立即获得第一个输出:

input_one string

然后五秒钟后,您会得到另一个回声:

input_two string

另一方面,首先使用“ sed”执行括号的所有内容,然后将其赋予“ sed”,因此命令

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

将输出两行

input_one string
input_two string

5秒后。

如果您正在执行对函数的调用,而这需要很长时间才能完成,并且想要不断地更新函数的输出,这将非常有用。


实际上,sed选项还可以立即处理每一行输入。
tomekwi's

对于单行输入,最简单的解决方案是echo input | (读v; echo $ {v} string)这是纯shell,因此不需要像sed这样的额外过程。
丹尼斯·豪

7

我知道这已经晚了几年,但是您可以使用xargs -J选项完成此操作:

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

由于它 xargs,因此您可以一次在文件的多行中执行此操作。如果文件“名称”有三行,例如:

Adam
Bob
Charlie

您可以这样做:

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

1
看起来很酷,但-J似乎不是标准/常见的。在Linux(xargs的一部分GNU findutils)上,我得到了错误:xargs: invalid option -- 'J'这是在哪个系统上?
arielf

3
-J适用于Mac版本。对于Linux -I执行相同的功能。
user2635263 '16

1
谢谢!很有用。请注意,在Linux上,此简化版本也可以正常工作: cat names | xargs -I% echo "I like % because he is nice"IOW:不需要-n 1(反正每行输入xargs调用echo一次,因为-I隐含-L1)而且,所有单独的arg引用似乎都是多余的。
arielf

3

您发布的命令将字符串“ input”用作COMMAND的stdin流,除非COMMAND首先打印出其stdin的内容,然后打印出其命令行参数,否则不会产生您要查找的结果。

似乎您想要做的事情更接近于命令替换。

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

使用命令替换,您可以拥有这样的命令行:

echo input `COMMAND "string"`

这将首先使用“ string”作为输入来评估COMMAND,然后将该命令执行的结果扩展到一行,替换'`'字符之间的内容。


当然是@NaomRoss,除非需要使用Bourne shell或具有其他疯狂的“可移植性”要求,否则,将使用诸如的现代命令替换echo input $(COMMAND "string"),而不是反引号。祝你们好运。
Shellter

1

猫将是我的选择: ls | cat - <(echo new line)


sed是基于行的命令,如果上游管道没有任何输出,该命令将不起作用
。–

0

也可以:

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

将生成类似以下的字符串:

string 000
string 001
string 002
string 003
string 004

...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.