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

  1. #!/usr/bin/env tclsh
  2.  
  3. # Apply a shell command to all of the files matching a glob, using xargs -0
  4. # to split the matching files across multiple commands if necessary.
  5.  
  6. # Usage: apply [-a] glob command
  7. # -a: do not exclude "hidden" files (beginning with .) from the glob results
  8.  
  9. # The glob should be quoted, to avoid having your shell expand it.
  10.  
  11. # The command should be given as multiple arguments, in the same form xargs
  12. # typically expects. For example,
  13. # apply '*.txt' grep -F 'foo bar'
  14.  
  15. # The glob results are not sorted.
  16.  
  17. # The exit status will be propagated from xargs. See xargs(1) for details.
  18.  
  19. # Due to a limitation in Tcl's [exec], arguments beginning with < or > or |
  20. # or 2> may cause errors. Sorry.
  21.  
  22. set all 0
  23. if {[lindex $argv 0] eq "-a"} {set all 1; set argv [lrange $argv 1 end]}
  24. if {[llength $argv] < 2} {
  25. puts stderr {usage: apply [-a] glob command}
  26. exit 1
  27. }
  28.  
  29. set glob [lindex $argv 0]
  30. set cmd [lrange $argv 1 end]
  31.  
  32. foreach f [glob -- $glob] {append files "$f\0"}
  33. if {$all} {
  34. foreach f [glob -nocomplain -types hidden -- $glob] {
  35. switch -glob -- $f {
  36. . - .. - */. - */.. {}
  37. default {append files "$f\0"}
  38. }
  39. }
  40. }
  41.  
  42. try {
  43. exec xargs -0 {*}$cmd << $files >@ stdout 2>@ stderr
  44. set status 0
  45. } trap CHILDSTATUS {results options} {
  46. set status [lindex [dict get $options -errorcode] 2]
  47. }
  48. exit $status
  49.