如何在命令行中将管道输入传递给ruby的-e选项?

22
我试图弄清楚如何在Bash控制台上编写一行代码并将其管道传递到Ruby,但我无法弄清楚如何获取输入。这样做不起作用:
echo "My String" | ruby -e "#{STDIN.read.first.downcase}"

如何在Ruby中获取管道输入?

3个回答

33

由于您的代码行以#开头,Ruby将其视为注释。

以下代码可以正常工作:

echo "My String" | ruby -e "puts gets.downcase"

输出:

my string

我使用了Kernel#gets而不是STDIN.gets

从ARGV(或$*)的文件列表中返回(并分配给$_)下一行,如果命令行上没有文件,则从标准输入中返回下一行。

如果你想处理每一行,你可以使用-p标志。它就像将你的脚本包装在一个while gets(); ... end; puts $_块中。Ruby将每个输入行读入$_,计算你的脚本并输出$_

echo "Foo\nBar\nBaz" | ruby -pe '$_.downcase!'

输出:

foo
bar
baz

1
OP的代码行不是以#(注释)开头,而是以#{...}表示字符串插值。OP的代码行没有输出任何内容,因为没有使用printputs命令。添加-p标志或使用-pe命令可以解决这个问题。 - the Tin Man
1
Ruby 会评估 #{},而不是 "#{}",所以它 一个注释。 - Stefan
尝试运行 echo "My String" | ruby -pe "#{just a comment}",你也会看到 My String ;) - Stefan
1
它读取输入行并在后面打印它们:假设while gets(); ... end循环围绕着您的脚本...但是像sed一样也要打印行。 您必须更改这些行以查看区别,例如: ls -1 | ruby -pe '$_.upcase!' - Stefan
1
啊,很好的观点。我改口了。回答时我正在对抗偏头痛真是自讨苦吃。叹气。 :-/ 我认为你已经准确地找到了OP的问题所在。干得好。 - the Tin Man
显示剩余3条评论

7

只需要

echo "My String" | ruby -ne 'puts $_.downcase'

或者

echo "My String" | ruby -e "puts gets.downcase"

你明白了。

7

示例:

去除所有行中的额外空格:

ls | ruby -e "STDIN.each_line.to_a.map(&:strip).each(&method(:puts))"

随机着色每一行:

ls | ruby -e "require 'colorize'; STDIN.each_line { |l| print l.colorize(String.colors.sample) }"

按长度排序行:

ls | ruby -e "puts STDIN.each_line.to_a.sort_by(&:size).reverse"

按文件大小排序文件:

ls -l | ruby -e 'STDIN.first; puts STDIN.each_line.to_a.map { |l| [l.split[4].to_i, l.split[8]] }.sort_by(&:first).reverse.map { |l| l.join("\t") }'

等等。等等。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接