Posted to tcl by greycat at Fri Apr 26 15:14:34 GMT 2019view pretty

#!/usr/bin/env tclsh

# Apply a shell command to all of the files matching a glob, using xargs -0
# to split the matching files across multiple commands if necessary.

# Usage: apply [-a] glob command
# -a: do not exclude "hidden" files (beginning with .) from the glob results

# The glob should be quoted, to avoid having your shell expand it.

# The command should be given as multiple arguments, in the same form xargs
# typically expects.  For example,
#   apply '*.txt' grep -F 'foo bar'

# The glob results are not sorted.

# The exit status will be propagated from xargs.  See xargs(1) for details.

# Due to a limitation in Tcl's [exec], arguments beginning with < or > or |
# or 2> may cause errors.  Sorry.

set all 0
if {[lindex $argv 0] eq "-a"} {set all 1; set argv [lrange $argv 1 end]}
if {[llength $argv] < 2} {
    puts stderr {usage: apply [-a] glob command}
    exit 1
}

set glob [lindex $argv 0]
set cmd [lrange $argv 1 end]

foreach f [glob -- $glob] {append files "$f\0"}
if {$all} {
    foreach f [glob -nocomplain -types hidden -- $glob] {
        switch -glob -- $f {
            . - .. - */. - */.. {}
            default {append files "$f\0"}
        }
    }
}

try {
    exec xargs -0 {*}$cmd << $files >@ stdout 2>@ stderr
    set status 0
} trap CHILDSTATUS {results options} {
    set status [lindex [dict get $options -errorcode] 2]
}
exit $status