如何为ruby -n -e提供$ INPUT_RECORD_SEPARATOR?

时间:2016-02-02 14:02:22

标签: ruby command-line io

我想使用Ruby的$ INPUT_RECORD_SEPARATOR aka $ /来操作选项卡分隔文件。

输入文件看起来像这样(非常简化):

a   b   c

(值由制表符分隔。)

我想获得以下输出:

a---
b---
c---

我可以使用ruby -e并设置$INPUT_RECORD_SEPARATOR别名$/轻松实现此目的:

cat bla.txt | ruby -e '$/ = "\t"; ARGF.each {|line| puts line.chop + "---" }'

这很有效,但我真正喜欢的是:

cat bla.txt | ruby -n -e '$/ = "\t"; puts $_.chop + "---" '

然而,这会打印出来:

a       b       c---

显然,它不使用提供的分隔符 - 可能是因为它已经在设置分隔符之前读取了第一行。我试图将其作为环境变量提供:

cat bla.txt | $/="\n" ruby -n -e 'puts $_.chop + "---" '

但是这会让shell感到困惑 - 它试图将$ /解释为命令(我也尝试用一个,两个,三个或四个反斜杠转义$,但都无济于事。)

那么如何将$ /与ruby -n -e结合起来?

2 个答案:

答案 0 :(得分:1)

使用-0选项:

cat bla.txt | ruby -011 -n -e 'puts $_.chop + "---" '
a---
b---
c---
  

-0 [octal]将默认记录分隔符($ /)设置为八进制。如果未指定八进制,则默认为\ 0.

标签的ascii代码为9,八进制为11.因此-011

答案 1 :(得分:1)

使用$ echo "foo\tbar\tbaz" | \ > ruby -n -e 'BEGIN { $/ = "\t" }; puts $_.chop + "---"' foo--- bar--- baz--- 块,在Ruby开始循环之前处理该块:

#!/usr/bin/env ruby -n
BEGIN {
  $/ = "\t"
}

puts $_.chop + "---"

或者,更可读:

$ chmod u+x script.rb
$ echo "foo\tbar\tbaz" | ./script.rb
foo---
bar---
baz---

然后:

$/ = ENV['IFS'] || "\t"

如果这不仅仅是一次性脚本(即其他人可能会使用它),则可以使用参数或环境变量对其进行配置,例如, repos