› Clovertech Forums › Read Only Archives › Cloverleaf › Cloverleaf › Zero legth files
I’d like to tcl’ize the command.
KSH:
find $HCISITEDIR/exec/processes/split2/smat -type f -size 0c -exec rm {} ;
TCL:
if {[catch {exec find ./ -type f -size 0c -exec rm {} ;} msg]} {
echo $msg
}
This doesn’t seem to work.
Any help would be appreciated.
Try escaping your {} and see if that works.
I ran the following test at the hcitcl interactive prompt which is mostly what you posted
exec find ./ -type f -size 0c -exec rm {} ;
and got the following error
Error: rm: A file or directory in the path name does not exist.
rm: A file or directory in the path name does not exist.
rm: A file or directory in the path name does not exist.
that borugh my attention to the {} so I escaped it as follows and the command worked
exec find ./ -type f -size 0c -exec rm {} ;
I still found myself wondering if I might need to be concered about escaping the in the ; but I will let you decide if you want to pursue that concern.
Russ Ross
RussRoss318@gmail.com
Yes, those end characters are giving me heartburn.
I kept changing my script but didn’t try the hcitcl> command line approach to troubleshooting.
Greetings,
Saw this post and there is Tcl code to get the size of a file using the “file” command. Here is a Tcl snippet from a fileset driver that we wrote to guess that a file is cooked before processing it (fileset/local):
# Check the file size, wait about 3-5 seconds, check again.
# Only release files that are complete – not changing size.
set msg_list [split [msgget $mh] ” “]
set outList {} ;#used to return the files to release
foreach fn $msg_list {
set fullFn [file join $IB_Directory ${fn}]
set preSize [file size $fullFn] # Similate a sleep for about 3 – 5 seconds next command.
# Would like the rest of the cmd threads to get time in this process.
loop idx 1 3000000 1 { }
set curSize [file size $fullFn]
# Allowing for a hang perhaps in file write – test for zero bytes.
if {$curSize > 0 && $curSize == $preSize} {
lappend outList ${fn}
}
Here’s a bit of code we use to do a similar thing, but we move them all to a directory called “zero”
system find ./* -size 0 -maxdepth 0 -print0 | xargs -0 -i mv {} zero ;
You have to escape the braces and the semicolon to get them past the command line parser so they can be seen by the find command.
Well, I can’t figure out how to escape it out correctly to run in a script.
I could do it command line, but failed with the script.
So I used Bob’s file size command in a foreach loop. (Thanks Bob)
Chris, I got further with system instead of exec but still no luck.
Apparently my flavor of unix (AIX6.1) doesn’t like the extended args.
Thanks for everyone’s ideas.
You can fully Tcl-ify the find-type functionality with something like the recursive procedure below.
You can then walk through the found files and delete them.
Or, you could just have the finder delete them whenever it finds one – your choice.
namespace eval findFiles {
}
proc findFiles::recursiveFindSmallFiles { filePath foundArrayName maxFileBytes } {
upvar $foundArrayName foundArray
set files [glob -nocomplain “$filePath/*”]
foreach f $files {
if { [file isdirectory $f] } {
findFiles::recursiveFindSmallFiles $f foundArray $maxFileBytes
} else {
set fs [file size $f]
if { $fs <= $maxFileBytes } {
set i $foundArray(numFound)
set foundArray($i,filePath) $f
set foundArray($i,fileSize) $fs
incr foundArray(numFound)
}
}
}
}
proc findFiles::findSmallFiles { dir foundArrayName maxFileBytes } {
upvar $foundArrayName foundArray
catch {unset foundArray}
set foundArray(numFound) 0
findFiles::getSmallFiles $dir foundArray $maxFileBytes
}
#
# Usage example
#
findFiles::findSmallFiles foundArray 0
for { set i 0 } { $i < $foundArray(numFound) } { incr i } {
# use file delete here if you want to delete the found files
puts "size= $foundArray($i,fileSize), path= $foundArray($i,filePath)"
}
Jeff Dinsmore
Chesapeake Regional Healthcare
email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.
It doesn’t need to be that complicated. I can’t see any need for uplevel at all…
The result can be passed by reference up and down the call stack with upvar alone.
Jeff Dinsmore
Chesapeake Regional Healthcare