在Bash中,我想比较两个不同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?
答案 0 :(得分:4)
它不起作用,因为正如你所得到的错误所表明的那样,Ruby会抨击sh,而不是Bash。当然,sh不支持该语法。
您可以明确地调用Bash:
`bash -c 'cat <(echo foo)'` #=> "foo"
答案 1 :(得分:0)
这是因为它只受bash的支持而不是sh?
是
sh不支持进程替换,即使sh实际上是bash(兼容性)。
答案 2 :(得分:0)
请勿尝试使用像cut
这样简单的内容来处理CSV文件中的字段。 CSV文件可以在字段内部嵌入逗号,这将欺骗,导致您的代码做错事。
相反,使用专门设计用于处理CSV文件的内容,例如Ruby的CSV类。像这个未经测试的代码会让你开始:
require 'csv' csv_file1 = CSV.open('file1') csv_file2 = CSV.open('file2') until (csv_file1.eof? || csv_file2.eof?) do row1 = csv_file1.shift row2 = csv_file2.shift # do something to diff the fields puts "#{ csv_file1.lineno }: #{ row1[1] } == #{ row2[2] } --> #{ row1[1] == row2[2] }" end [ [csv_file1, 'file1'], [csv_file2, 'file2'] ].each do |f, fn| puts "Hit EOF for #{ fn }" if f.eof? f.close end