Question

I'm learning tcl (expect) and now I came to an interesting issue. I need a command to move/rename a bunch of files with extension .status. I tried these:

spawn /bin/mv *.status some_dir
exec /bin/mv *.status some_dir

Of course, that did not work. I googled a bit and found something about glob, but it doesn't seem to work the way I want it to. If I do:

exec /bin/mv [glob *.status] somedir

mv complains that '1.status 2.status 3.status...etc.' is not a valid file. It as if the whole list of files is concatenated in a single string instead of being treated separately.

Trying to find more information via google lead me to a lot of broken and outdated links, so I'm hoping beside solving this problem, could you point me to some good online resource for tcl/expect basics and common pitfalls.

Update: Only solutions that use standard tcl and standard tools in /bin will be accepted.

Was it helpful?

Solution

$ ls -1
1.status
2.status
rename.tclsh*
some_dir/
two words.status

$ cat rename.tclsh
#!/usr/local/bin/tclsh

eval exec /bin/mv [glob *.status] some_dir

$ ./rename.tclsh

$ ls -1
rename.tclsh*
some_dir/

$ ls -1 some_dir/
1.status
2.status
two words.status

OTHER TIPS

Randy's answer is short and correct but uses an exec without need. Joseph's answer is very robust but a bit long.

For a short and idiomatic answer I would use (requires Tcl 8.5):

file rename {*}[glob *.status] some_dir

proc move_to_dir {filenames dirname} {
    foreach filename $filenames {
        file rename $filename [file join $dirname [file tail $filename]]
    }
}
# Example:
move_to_dir [glob -nocomplain *.status] ~/foo/bar/

This solution works with files with names containing spaces, when there is a lot of files etc:

exec find -maxdepth 1 -name *.status -print0 | xargs -0 mv -t some_dir

But it needs find and xargs which are most often in /usr/bin, not /bin.

As a safety feature when using complex 'find' commands and potentially deleting data I stick an 'echo' in front of the command and capture it to a file.
I can then check the commands listed in the file before using 'source' to run it.

It's also a way of handling those occasional edge case files manually.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top