Ruby wildcard command line argument auto expansion

I want to pass in wildcard file names, and use it to match file names
located in different directories. For example, *.txt will match file
such as “my.txt”, “you.txt”, etc.

However, I found out ruby intepreter automatically expands “*.txt”
command argument to a array of filenames which matches that wildcard in
the current directory.

For example:

C:\working>dir *.txt

05/10/2007 03:24 PM 46,101 config.txt
11/23/2004 11:54 AM 361 tips.txt
2 File(s) 46,462 bytes

If you do,

C:\working>ruby -e “puts ARGV” *.txt
config.txt
tips.txt

Ruby converts string *.txt into the matching filenames and pass in the
expanded array as the new argument.

This nice trick sometime creates trouble.

In my case, I want to use ‘ARGV[0]’ to match filenames in a different
location. But ARGV[0] is not “*.txt” as my expected. It was changed by
ruby. In fact, it is “config.txt” in this case.

One way to correct it is to always ask user to use single-quoted string:

C:\working>ruby -e “puts ARGV” ‘*.txt’
*.txt

Is there a better way to disbale this auto expansion?

Thanks
Michael

One way to correct it is to always ask user to use single-quoted string:

C:\working>ruby -e “puts ARGV” ‘*.txt’
*.txt

Michael Jia wrote:

The filename expansion is a function of the command window, not Ruby. By
the time Ruby starts up the expansion has already happened. I think the
only way to disable it is to put quotes around the argument.

Hallo Michael,

it’s not Ruby, that expands your argument, but the shell. And
therefore you got no other chance than escaping the argument there.

This can be done using quotes or a backslash in front of each special
character

ruby -e “puts ARGV” *.txt

Best,

Gregor

I did some further research on this topic. My win xp cmd shell seems
doesn’t do wildcard expansion by itself.

C:\working>echo *.txt
*.txt

There are some posts saying the VC C runtime library is the one actually
does wildcard expansion. As seen here:
http://www.lyra.org/pipermail/scite-interest/2002-March/000436.html

A similar behavior in Java was also reported here,
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6328875
http://mindprod.com/jgloss/main.html
http://groups.google.com/group/comp.lang.java.programmer/browse_thread/thread/a6f188a2d521803e?hl=en&lr=&ie=UTF-8&oe=UTF-8&frame=right&seekm=01be589d%24dc827700%24baac72d1%40stargate.sgi.net

It seems to me that it is the ruby intepreter was linked to the runtime
library, namely, startargv.obj, then it gets the expansion for free. :slight_smile:

Can someone familiar with ruby build please clarify?

Thanks you all for the reply.
I blog this thread in
http://zhifengjia.spaces.live.com/blog/cns!5D88F9EA36578152!218.entry
Hopefully, it will appear in search engine’s list to save ppl time.

Gregor Schmidt wrote:

Hallo Michael,

it’s not Ruby, that expands your argument, but the shell. And
therefore you got no other chance than escaping the argument there.

This can be done using quotes or a backslash in front of each special
character

ruby -e “puts ARGV” *.txt

Best,

Gregor

On Jun 9, 2007, at 2:18 PM, Michael Jia wrote:

It seems to me that it is the ruby intepreter was linked to the
runtime
library, namely, startargv.obj, then it gets the expansion for
free. :slight_smile:

Can someone familiar with ruby build please clarify?


Posted via http://www.ruby-forum.com/.

rab:Users/rab $ mkdir tmp
rab:Users/rab $ cd tmp
rab:rab/tmp $ touch foo.txt bar.pdf baz.rb
rab:rab/tmp $ echo *.txt
foo.txt
rab:rab/tmp $ echo *.pdf
bar.pdf
rab:rab/tmp $ echo *.java
*.java
rab:rab/tmp $

It also depends what is in the directory at the time of the
expansion. If there are no files that match the glob pattern, the
shell (bash in this case) passes the argument as is (just as if it
had been ‘*.java’).

rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ .
bar.pdf - baz.rb - foo.txt
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ *.txt
foo.txt
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ *.pdf
bar.pdf
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ *.java
.java
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ b

bar.pdf - baz.rb
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ f
bar.pdf - foo.txt
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ ‘f
f

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

I am using Windows XP “cmd” shell. What you described is true for unix
bash or C-shell.

C:\working>dir *.txt
Volume in drive C has no label.
Volume Serial Number is 5471-FCF7

Directory of C:\working

05/10/2007 03:24 PM 46,101 config.txt
11/23/2004 11:54 AM 361 tips.txt
2 File(s) 46,462 bytes
0 Dir(s) 32,580,259,840 bytes free

C:\working>echo *.txt
*.txt

That is why I think it is the ruby intepreter in Windows does the
expansion.

Regards
Michael

Rob B. wrote:

On Jun 9, 2007, at 2:18 PM, Michael Jia wrote:

It seems to me that it is the ruby intepreter was linked to the
runtime
library, namely, startargv.obj, then it gets the expansion for
free. :slight_smile:

Can someone familiar with ruby build please clarify?


Posted via http://www.ruby-forum.com/.

rab:Users/rab $ mkdir tmp
rab:Users/rab $ cd tmp
rab:rab/tmp $ touch foo.txt bar.pdf baz.rb
rab:rab/tmp $ echo *.txt
foo.txt
rab:rab/tmp $ echo *.pdf
bar.pdf
rab:rab/tmp $ echo *.java
*.java
rab:rab/tmp $

It also depends what is in the directory at the time of the
expansion. If there are no files that match the glob pattern, the
shell (bash in this case) passes the argument as is (just as if it
had been ‘*.java’).

rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ .
bar.pdf - baz.rb - foo.txt
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ *.txt
foo.txt
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ *.pdf
bar.pdf
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ *.java
.java
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ b

bar.pdf - baz.rb
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ f
bar.pdf - foo.txt
rab:rab/tmp $ ruby -e ‘puts ARGV.join(" - ")’ ‘f
f

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Rob, the result is:

C:\working>ruby -e “puts ARGV.join(’ - ')” *.txt
config.txt - tips.txt

C:\working>ruby -e “puts ARGV.join(’ - ')” “*.txt”
config.txt - tips.txt

Thanks
Michael

Rob B. wrote:

In that case, you should run these two commands:

c:\working> ruby -e “puts ARGV.join(’ - ')” *.txt

c:\working> ruby -e “puts ARGV.join(’ - ')” “*.txt”

and they should produce the same output
(i.e., “config.txt - tips.txt” or “tips.txt - config.txt”)
if the work is being done by the interpreter.

If one of them produces simply “*.txt” (probably the second), then
something different is going on.

-Rob

In that case, you should run these two commands:

c:\working> ruby -e “puts ARGV.join(’ - ')” *.txt

c:\working> ruby -e “puts ARGV.join(’ - ')” “*.txt”

and they should produce the same output
(i.e., “config.txt - tips.txt” or “tips.txt - config.txt”)
if the work is being done by the interpreter.

If one of them produces simply “*.txt” (probably the second), then
something different is going on.

-Rob

OK, then it look like your ‘ruby’ really is doing some form of
filename expansion for command-line arguments. However, not using
Windows myself, there’s no way that I could help you more than this.
I do find it interesting though.

-Rob

On Jun 9, 2007, at 6:16 PM, Michael Jia wrote:

If one of them produces simply “*.txt” (probably the second), then
something different is going on.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Hi,

At Sat, 9 Jun 2007 18:39:30 +0900,
Michael Jia wrote in [ruby-talk:254917]:

In my case, I want to use ‘ARGV[0]’ to match filenames in a different
location. But ARGV[0] is not “*.txt” as my expected. It was changed by
ruby. In fact, it is “config.txt” in this case.

One way to correct it is to always ask user to use single-quoted string:

C:\working>ruby -e “puts ARGV” ‘*.txt’
*.txt

It’s the only way.

I think you should use '.txt’ instead of ".txt". Here the output from
my WinXP:

C:>ruby -e “puts ARGV.join(’ - ')” *.txt
atlog.txt - ClientCfg.txt - dfsinfo.txt - ipconfig.txt -
javainstalls.txt - NewG
zCompressedFile.txt - sdatlog.txt - setregion.txt - trace.txt

C:>ruby -e “puts ARGV.join(’ - ')” ‘*.txt’
*.txt

C:>ruby -e “puts ARGV.join(’ - ')” “*.txt”
atlog.txt - ClientCfg.txt - dfsinfo.txt - ipconfig.txt -
javainstalls.txt - NewG
zCompressedFile.txt - sdatlog.txt - setregion.txt - trace.txt

C:>ruby --version
ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32]

C:>

Shin guey Wong wrote:

I think you should use '.txt’ instead of ".txt". Here the output from
my WinXP:

I think Ruby is wrong to change the OS standard. On unix the standard
is to expand as filenames (fine). On windows the standard is NOT to
expand wildcards.

I use wildcards for non filename lookups (i.e. to match users in an
LDAP)

Example in Pthon
C:> finduser.py pa*
user paul found

Same in Ruby
C:> finduser.rb pa*

  • and it goes looking for a user with a name matching some file in the
    current directory.

I accept that on unix it SHOULD require quotes or escaping but not on
Windows.

On windows the ARGV should be “pa*” as typed.