.bz2、.gz、.txtの3種類のファイルを開くユーティリティ関数を作成しようとしています。File.read圧縮ファイルのゴミが戻ってくるので、そのまま使用することはできません。別のコマンドを指定できるように使用しようとしてOpen3.popen3いますが、次のコードで「そのようなファイルまたはディレクトリはありません」というエラーが発生します。
def file_info(file)
cmd = ''
if file.match("bz2") then
cmd = "bzcat #{file}"# | head -20"
elsif file.match("gz") then
cmd = "gunzip -c #{file}"
else
cmd = "cat #{file}"
end
puts "opening file #{file}"
Open3.popen3("#{cmd}", "r+") { |stdin, stdout, stderr|
puts "stdin #{stdin.inspect}"
stdin.read {|line|
puts "line is #{line}"
if line.match('^#') then
else
break
end
}
}
end
> No such file or directory - cat /tmp/test.txt
ファイルは存在します。cmdの代わりにを使用してみまし#{cmd}たが、同じ結果になりましたpopen3 cmd。
次のようにtxtファイルを実行するようにハードコーディングすることにしました。
def file_info(file)
puts "opening file #{file}"
Open3.popen3("cat", file, "r+") { |stdin, stdout, stderr|
puts "stdin #{stdin.inspect}"
stdin.read {|line|
puts "line is #{line}"
if line.match('^#') then
else
break
end
}
}
end
これは私に戻ってきます:
stdin #<IO:fd 6>
not opened for reading
私は何が間違っているのですか?
私がする時:
Open3.popen3("cat",file) { |stdin, stdout, stderr|
puts "stdout is #{stdout.inspect}"
stdout.read {|line|
puts "line is #{line}"
if line.match('^#') then
puts "found line #{line}"
else
break
end
}
}
エラーは発生せず、STDOUT行が出力されますが、どちらの行ステートメントも何も出力しません。
いくつかの異なることを試した後、私が思いついた解決策は次のとおりでした。
cmd = Array.new
if file.match(/\.bz2\z/) then
cmd = [ 'bzcat', file ]
elsif file.match(/\.gz\z/) then
cmd = [ 'gunzip', '-c', file ]
else
cmd = [ 'cat', file ]
end
Open3.popen3(*cmd) do |stdin, stdout, stderr|
puts "stdout is #{stdout}"
stdout.each do |line|
if line.match('^#') then
puts "line is #{line}"
else
break
end
end
end