1

在 Bash 中,我想比较 2 个不同 CSV 的字段(file1 的字段 2 和 file2 的字段 3):

diff <(cut -d, -f2 file1) <(cut -d, -f3 file2)

我尝试在 Ruby 中更普遍地实现这一点:

def identical_files?(file1, field1, file2, field2)                                                                                                              
  %x{diff <(cut -d, -f#{field1} #{file1}) <(cut -d, -f#{field2} #{file2})}.blank?                                   
end

打印%x{}块的输出,我看到了sh: Syntax error: "(" unexpected。在 Ruby 中运行 shell 命令时,I/O 重定向是否不起作用?这是因为它只支持 bash 而不是 sh?

4

3 回答 3

4

它不起作用,因为正如您收到的错误所示,Ruby 向 sh 发送,而不是 Bash。而且,当然, sh 不支持该语法。

您可以改为显式调用 Bash:

`bash -c 'cat <(echo foo)'`  #=> "foo"
于 2013-02-08T04:33:24.267 回答
0

这是因为它只支持 bash 而不是 sh?

是的。

sh 不支持进程替换,即使 sh 实际上是 bash(为了兼容性)。

于 2013-02-08T04:33:10.053 回答
0

不要尝试使用像cut处理 CSV 文件中的字段这样简单的东西。CSV 文件可以在字段内嵌入逗号,这样会傻瓜式地剪切,导致您的代码做错事。

相反,使用专门设计用于处理 CSV 文件的东西,例如 Ruby 的CSV类。像这样未经测试的代码会让你开始:

需要'csv'

csv_file1 = CSV.open('file1')
csv_file2 = CSV.open('file2')

直到 (csv_file1.eof?|| csv_file2.eof?) 做
  row1 = csv_file1.shift
  row2 = csv_file2.shift

  # 做一些事情来区分字段
  提出“#{ csv_file1.lineno }: #{ row1[1] } == #{ row2[2] } --> #{ row1[1] == row2[2] }”
结尾

[
  [csv_file1, 'file1'],
  [csv_file2, 'file2']
].每个都做 |f, fn|
  如果 f.eof? 将 "Hit EOF for #{ fn }"
  f.close
结尾

于 2013-02-08T06:06:50.110 回答