Zero legth files

Clovertech Forums Read Only Archives Cloverleaf Cloverleaf Zero legth files

  • Creator
    Topic
  • #53374
    Michael Hertel
    Participant

      We have a ksh script that cleans up zero length 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.

    Viewing 7 reply threads
    • Author
      Replies
      • #77466
        Russ Ross
        Participant

          Try escaping your {} and see if that works.

          I ran the following test at the hcitcl interactive prompt which is mostly what you posted

          Code:

          exec find ./ -type f -size 0c -exec rm {} ;

          and got the following error

          Code:

          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

        • #77467
          Michael Hertel
          Participant

            Thanks Russ, I’ll give that a try.

            Yes, those end characters are giving me heartburn.

            I kept changing my script but didn’t try the hcitcl> command line approach to troubleshooting.

          • #77468
            Bob Richardson
            Participant

              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}

                                      }

            • #77469
              Chris Williams
              Participant

                Here’s a bit of code we use to do a similar thing, but we move them all to a directory called “zero”

                Code:

                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.

              • #77470
                Michael Hertel
                Participant

                  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.

                • #77471
                  Jeff Dinsmore
                  Participant

                    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.

                    Code:

                    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

                  • #77472
                    Jim Kosloskey
                    Participant

                      Take a look at for_recursive_glob command for something which I have found useful for finding across the breadth and depth of a direcftory structure.

                      email: jim.kosloskey@jim-kosloskey.com 30+ years Cloverleaf, 60 years IT – old fart.

                    • #77473
                      Jeff Dinsmore
                      Participant

                        Yikes!  That is one convoluted proc.

                        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

                    Viewing 7 reply threads
                    • The forum ‘Cloverleaf’ is closed to new topics and replies.