Ruby wildcard command line argument auto expansion

M

Michael Jia

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
 
T

Tim Hunter

Michael said:
Is there a better way to disbale this auto expansion?

Thanks
Michael
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.
 
G

Gregor Schmidt

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 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
 
M

Michael Jia

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/[email protected]

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. :)

Can someone familiar with ruby build please clarify?
 
R

Rob Biedenharn

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. :)

Can someone familiar with ruby build please clarify?

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 Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
M

Michael Jia

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
 
R

Rob Biedenharn

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
 
M

Michael Jia

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
 
R

Rob Biedenharn

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

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 Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
S

Shin guey Wong

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:\>
 
N

Nobuyoshi Nakada

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.
 
P

Paul Denize

Shin said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top