From: David Jacobs Date: 2012-09-01T13:42:22+09:00 Subject: Re: Parsing unix filenames from STDIN FYI I ended up using the following (turns out I didn't need bash expansion because I'll always get that from the previous tool in the pipeline): if $stdin.tty? # … do something else files = $stdin.each_line.reduce([]) do |list, line| list.concat(Shellwords.split(line)) end # … do something with files end On Monday, August 27, 2012 at 2:51 AM, Robert Klemme wrote: > On Sat, Aug 25, 2012 at 11:51 AM, Sean O'Halpin wrote: > > On Sat, Aug 25, 2012 at 12:57 AM, David Jacobs wrote: > > > How can I parse filenames read from STDIN via the standard Unix parsing rules (without duplicating said rules)? All of the following would be parsed as coherent file names: > > > > > > file.txt > > > my\ file.txt > > > "my file.txt" > > > > > > A nice addition would be that *.txt would use Bash expansion to find the appropriate files. > > > > Use Shellwords to handle shell escaped strings and Dir[] to expand wildcards: > > > > require 'shellwords' > > while line = STDIN.gets > > filename = Shellwords.shellwords(line).join('') > > p filename > > # expand wildcards > > p Dir[filename] > > end > > > > Two additional cents: > > 1. I'd rather use $stdin instead of STDIN, see here for reasoning: > http://stackoverflow.com/questions/4279604/what-is-the-difference-between-stdin-and-stdin-in-ruby > > 2. One can as well use the usual iteration for reading lines from files. > > => > > require 'shellwords' > > $stdin.each_line do |line| > filename = Shellwords.shellwords(line).join('') > p filename > # expand wildcards > p Dir[filename] > end > > Advantage is also that the scope of "line" is limited to the block > reducing potential for errors. > > Btw, Sean, are you sure David will join all the shellwords? I am > asking since he said there were commands as well and he basically > wants to parse in the same way the shell does. So: > > irb(main):006:0> ['my\\ file.txt', '"my file.txt"', 'ls foo\\ > bar.txt'].each {|s| printf "%p -> %p\n", s, Shellwords.shellwords(s)} > "my\\ file.txt" -> ["my file.txt"] > "\"my file.txt\"" -> ["my file.txt"] > "ls foo\\ bar.txt" -> ["ls", "foo bar.txt"] > => ["my\\ file.txt", "\"my file.txt\"", "ls foo\\ bar.txt"] > > > Kind regards > > robert > > -- > remember.guy do |as, often| as.you_can - without end > http://blog.rubybestpractices.com/