[comp.unix.questions] cleanup script needed

rkumar@buddha.usc.edu (03/05/89)

This may be quite silly to the UNIX wizards.

1) Frequently I need to erase unnecessary files to save space.
It would be nice to have a script which removes all
the files with a specified extension, e.g., .dvi or .aux
not only in the current directory, but in all the 
children directories recursively. 
Will rm -r *.dvi do the job? Since it is an "rm" command,
I don't want to try it out ... 

2) Sometimes I create a file in a directory which is deep
down in a directory hierarchy. Any quick way to search for
a file, given its name/template?

Thanks 
Ravi
--- :-)
Pardon me, but UNIX *is* male chauvinistic. Look at all those
*man* commands!
--- :-(

gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/05/89)

In article <15659@oberon.USC.EDU> rkumar@buddha.usc.edu () writes:
>Will rm -r *.dvi do the job?

No, try	"find . -name '*.dvi' -print | xargs rm".

>Any quick way to search for a file, given its name/template?

"find . -name whatever -print"

spolsky-joel@CS.YALE.EDU (Joel Spolsky) (03/06/89)

In article <15659@oberon.USC.EDU> rkumar@buddha.usc.edu () writes:
>This may be quite silly to the UNIX wizards.
>
>1) Frequently I need to erase unnecessary files to save space.
>It would be nice to have a script which removes all
>the files with a specified extension, e.g., .dvi or .aux
>not only in the current directory, but in all the 
>children directories recursively. 
>Will rm -r *.dvi do the job? Since it is an "rm" command,
>I don't want to try it out ... 
>
>2) Sometimes I create a file in a directory which is deep
>down in a directory hierarchy. Any quick way to search for
>a file, given its name/template?
>
>Thanks 
>Ravi
>--- :-)
>Pardon me, but UNIX *is* male chauvinistic. Look at all those
>*man* commands!
>--- :-(


Look into the find command. It's kinda complicated so it's worth
reading the manual page. Basically find produces a list of files that
satisfy given criteria.

+----------------+----------------------------------------------------------+
|  Joel Spolsky  | bitnet: spolsky@yalecs.bitnet     uucp: ...!yale!spolsky |
|                | internet: spolsky@cs.yale.edu     voicenet: 203-436-1483 |
+----------------+----------------------------------------------------------+
                                                      #include <disclaimer.h>

wu@spot.Colorado.EDU (WU SHI-KUEI) (03/06/89)

find . \( -name "*.dvi*" -o -name "*.aux*" \) -ok rm {} \;

should do it - if you don't want to confirm every 'rm' command, use
-exec instead of -ok.  See the manual page!!

david@torsqnt.UUCP (David Haynes) (03/06/89)

In article <9793@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
:In article <15659@oberon.USC.EDU> rkumar@buddha.usc.edu () writes:
:>Will rm -r *.dvi do the job?
:
:No, try	"find . -name '*.dvi' -print | xargs rm".
:
Why not, 	"find . -type f -name '*.dvi' -exec rm {} \;" 	?

-david-

gwyn@smoke.BRL.MIL (Doug Gwyn ) (03/06/89)

In article <80@torsqnt.UUCP> david@torsqnt.UUCP (David Haynes) writes:
>Why not, 	"find . -type f -name '*.dvi' -exec rm {} \;" 	?

From the context of his question, the "-type f" seemed unnecessary.
The reason for using xargs instead of -exec is to make the command
finish in less time.  (I know BSD systems often don't have xargs,
but presumably one could use the "apply" utility instead.)

wu@spot.Colorado.EDU (WU SHI-KUEI) (03/07/89)

In article <80@torsqnt.UUCP> david@torsqnt.UUCP (David Haynes) writes:
>In article <9793@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>:In article <15659@oberon.USC.EDU> rkumar@buddha.usc.edu () writes:
>:>Will rm -r *.dvi do the job?
>:
>:No, try	"find . -name '*.dvi' -print | xargs rm".
>:
>Why not, 	"find . -type f -name '*.dvi' -exec rm {} \;" 	?

The 'xargs' version will be many times faster than the 'exec' version since the
latter invokes 'rm' for every file found while 'xargs' will invoke 'rm' only
once for every 470 characters in the command list (including spaces).

mark@motcsd.UUCP (Mark Jeghers) (03/08/89)

In article <80@torsqnt.UUCP> david@torsqnt.UUCP (David Haynes) writes:
>In article <9793@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>:In article <15659@oberon.USC.EDU> rkumar@buddha.usc.edu () writes:
>:>Will rm -r *.dvi do the job?
>:
>:No, try	"find . -name '*.dvi' -print | xargs rm".
>:
>Why not, 	"find . -type f -name '*.dvi' -exec rm {} \;" 	?
>
>-david-


Becuase using "-exec rm {}" will invoke a "rm" process for each file found.
"xargs", on the other hand, will assemble as big of an argument list as
possible and invoke ONE "rm" process for that argument list.  "xargs" will
then start on another argument list and repeat the process until all the
file names being piped into it are used up.  This results in *much* fewer
invocations of "rm", and is thus more efficient.

Mark Jeghers
Motorola Computer Systems

levy@ttrdc.UUCP (Daniel R. Levy) (03/10/89)

In article <80@torsqnt.UUCP>, david@torsqnt.UUCP (David Haynes) writes:
> :No, try	"find . -name '*.dvi' -print | xargs rm".
> :
> Why not, 	"find . -type f -name '*.dvi' -exec rm {} \;" 	?

Which is better in some ways, since in the first example (using xargs) if rm
finds a *.dvi file without write permission to you or which it otherwise thinks
is unsuitable to be removed, it will say something like

foo/bar.dvi: 444 mode?

and then read a line from stdin.  This will swallow the next filename from
find, which was intended for xargs.  Of course rm -f will omit the check but
also will omit any warning for files you can't remove or that can be removed
but are not writeable by you.
-- 
Daniel R. Levy             UNIX(R) mail:  att!ttbcad!levy
AT&T Bell Laboratories
5555 West Touhy Avenue     Any opinions expressed in the message above are
Skokie, Illinois  60077    mine, and not necessarily AT&T's.

guy@auspex.UUCP (Guy Harris) (03/14/89)

>it will say something like
>
>foo/bar.dvi: 444 mode?
>
>and then read a line from stdin.

But the 4.3BSD and S5R3 ones appear not to do so if the standard input
isn't a tty, so if they're reading from the pipe in question, they won't
ask.

rbj@dsys.icst.nbs.gov (Root Boy Jim) (04/04/89)

? From: David Haynes <david@torsqnt.uucp>
? Date: 6 Mar 89 00:22:17 GMT

? In article <9793@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
? :In article <15659@oberon.USC.EDU> rkumar@buddha.usc.edu () writes:
? :>Will rm -r *.dvi do the job?
? :
? :No, try	"find . -name '*.dvi' -print | xargs rm".
? :
? Why not, 	"find . -type f -name '*.dvi' -exec rm {} \;" 	?

? -david-

As has been pointed out, the xargs version is much better. However, in
our never ending search for creeping featurism, perhaps it is time to
add `-rm' to the list of find options. We already have `-ls'.

	Catman Rshd <rbj@nav.icst.nbs.gov>
	Author of "The Daemonic Versions"

drears@PICA.ARMY.MIL (Dennis G. Rears (FSAC)) (05/08/89)

rkumar@buddha.usc.edu  writes:
>
>This may be quite silly to the UNIX wizards.
>
>1) Frequently I need to erase unnecessary files to save space.
>It would be nice to have a script which removes all
>the files with a specified extension, e.g., .dvi or .aux
>not only in the current directory, but in all the 
>children directories recursively. 
>Will rm -r *.dvi do the job? Since it is an "rm" command,
>I don't want to try it out ... 

  /bin/find DIR -name "*.dvi" -exec rm -f {} \;

  DIR is the directory that is where you want to start from.  The
*.dvi must be enclosed in quotes.  You might want to use the -i option of
rm as opposed to -f depending upon application. 
>
>2) Sometimes I create a file in a directory which is deep
>down in a directory hierarchy. Any quick way to search for
>a file, given its name/template?
>
  /bin/find DIR -name "filename" -exec ls -l {} \;

   This will do it.  This will give the full path name.
>Thanks 
>Ravi


Dennis

			Dennis G. Rears
			ARPA: drears@ac4.pica.army.mil   
			UUCP:  ...!uunet!ac4.pica.army.mil!drears

exodus@cheers.UUCP (Greg Onufer) (05/10/89)

In article <19510@adm.BRL.MIL>, drears@PICA.ARMY.MIL (Dennis G. Rears (FSAC)) writes:
>   /bin/find DIR -name "filename" -exec ls -l {} \;
> 
>    This will do it.  This will give the full path name.

Ouch!  Too much processor time is being wasted!

Try:

	find DIR -name 'filename' -print  

to get just the pathname, or:

	find DIR -name 'filename' -ls

To get a directory listing (is the -ls flag standard or just a 
SunOS'ism?).

Find is one of the most powerful Unix utilities, but has too many
command-line switches!  This causes it to be mis-used or never-used
by a lot of people who really need such a utility.

-greg

guy@auspex.auspex.com (Guy Harris) (05/11/89)

>	find DIR -name 'filename' -ls
>
>To get a directory listing (is the -ls flag standard or just a 
>SunOS'ism?).

The answer to the question is "no" - it's neither standard, nor is it a
SunOSism.  It's a BSDism (which was folded into the S5-based "find"s in
later SunOS releases).  If you don't have it, you may have "xargs",
which can bundle up the output of "find" and run one "ls" command for
every N files, not just for every file.

>Find is one of the most powerful Unix utilities, but has too many
>command-line switches!  This causes it to be mis-used or never-used
>by a lot of people who really need such a utility.

Or, to quote (at least some versions of) the man page:

     BUGS
	The syntax is painful.

jeff@quark.WV.TEK.COM (Jeff Beadles;X2568;61-215) (05/11/89)

In article <19510@adm.BRL.MIL> drears@PICA.ARMY.MIL (Dennis G. Rears (FSAC)) writes:
>
>  /bin/find DIR -name "*.dvi" -exec rm -f {} \;
>
>  DIR is the directory that is where you want to start from.  The
>*.dvi must be enclosed in quotes.  You might want to use the -i option of
>rm as opposed to -f depending upon application. 

Rather than using '-exec rm -i {} \;', why not use:

	'-ok rm {} \;'

That way, rm is not called for files that you don't want to remove.

	-Jeff

--
Jeff Beadles		Utek Sustaining Engineering, Tektronix Inc.
jeff@quark.WV.TEK.COM

dans@hplsla.HP.COM (Dan Siler) (05/12/89)

This is a script that does various types of file cleanup. Be sure to
carefully review it before firing it up! I have cron launch this once a week.

 _________________________________________________________________________
|                                                                         |
| Dan Siler          unix: dans%hplsla@hplabs.hp.com hplabs!hplsla!dans   |
| Hewlett Packard                           hpdesk: DAN SILER/HPA100/15   |
| Lake Stevens Instrument Division, ms:380           at&t: (206) 335-2178 |
| 8600 Soper Hill Road;  Everett, WA 98205-1298        telnet: 1-335-2178 |
|_________________________________________________________________________|


#!/bin/sh
#---------------------------------
#  CONFIGURE THESE
# 
#  variable="true" implies true or yes--do this action
#  Anything else (i.e. "false" implies false, or no--don't do this action)

rm_catpages="true"   # rm nroffed cat pages (only if the un-nroffed page exists)
rm_junkfiles="false" # rm junk files listed in the variable $junkfiles
mailroot="true"      # Mail a summary of what was truncated/cleaned-up
script="$0"                            # Name of this script
subject="`hostname` `basename $0` ran" # Subject for mailing
to="root"                              # Who to mail to

files="
/etc/ptydaemonlog
/etc/vtdaemonlog
/usr/adm/inetd.log
/usr/adm/neterrlog
/usr/adm/nfslog
"

nochangefile="
/etc/wtmp
/etc/btmp
"

# Note: Any files matching these names will be removed from the system.
#       A very dangerous command.
junkfiles="
core
a.out
dead.letter
"
#
#---------------------------------

{
echo "Execution trace of $script..."
echo "1) assign mailroot variable to 'false' if this mail message is not desired."
echo "2) assign rm_catpages variable 'true' if removal of cat pages is desired."
echo "3) assign rm_junkfiles variable 'true' if removal of junk files is desired."
echo ""
for i in $files
do
  if [ -f "${i}" ]
  then
    echo "truncating $i..."
    echo "  - new is tail of old, old copy in ${i}.old"
    cp ${i} ${i}.old
  fi
  tail ${i}.old >${i}
  echo "" >> ${i}
  echo Log file beginning on `date "+%D at %r"` >> ${i}
  echo "" >> ${i}
  chmod 440 ${i}.old
done


if [ -f "/usr/adm/sulog" ]
then
  echo "truncating /usr/adm/sulog..."
  echo "  - new is tail of old, old copy in /usr/adm/OLDsulog"
  cp /usr/adm/sulog /usr/adm/OLDsulog
fi
tail /usr/adm/OLDsulog >/usr/adm/sulog
echo "" >> /usr/adm/sulog
echo Log file beginning on `date "+%D at %r"` >> /usr/adm/sulog
echo "" >> /usr/adm/sulog
chmod 440 /usr/adm/OLDsulog

if [ -f "/usr/lib/cron/log" ]
then
  echo "truncating /usr/lib/cron/log..."
  echo "  - new is tail of old, old copy in /usr/lib/cron/OLDlog"
  cp /usr/lib/cron/log /usr/lib/cron/OLDlog
fi
tail /usr/lib/cron/OLDlog >/usr/lib/cron/log
echo "" >> /usr/lib/cron/log
echo Log file beginning on `date "+%D at %r"` >> /usr/lib/cron/log
echo "" >> /usr/lib/cron/log
chmod 440 /usr/lib/cron/OLDlog

for i in $nochangefile
do
  if [ -f "${i}" ]
  then
    echo "truncating $i..."
    echo "  - old copy in $i.old"
    mv ${i} ${i}.old
  fi
  touch $i
  chmod 440 $i
done

if [ "${rm_catpages}" = "true" ]
then
  # remove old manual pages from /usr/man/cat1
  # (There only needs to be the nroff source file from /usr/man/man1)
  # files older than 14 days are removed.
  echo "looking for formatted manual pages..."
  manmandirs=`echo /usr/man/man* /usr/contrib/man/man* /usr/local/man/man*`
  dirlist=""
  for dir in ${manmandirs}
  do
    if [ -d ${dir} ]
    then
      dirlist="${dirlist}${dir} "
    fi
  done

  for dir in /usr/man /usr/contrib/man /usr/local/man
  do
    if [ -d "${dir}" ]
    then
      for i in 1 1m 2 3 4 5 6 7 8 9
      do
        if [ -d "${dir}/cat${i}" ]
        then
          cd "${dir}/cat${i}"
          for catpage in `find . -ctime +14 -print`
          do
            if [ -f "${dir}/man${i}/${catpage}" ]
            then
              echo "removing ${dir}/cat${i}/${catpage}..."
              rm ${dir}/cat${i}/${catpage}
            fi
          done
        fi
      done
    fi
  done
fi

# remove junk files

if [ "${rm_junkfiles}" = "true" ]
then
  for i in $junkfiles
  do
    echo "removing any $i junk files..."
    find / -name $i -exec rm {} \;
  done
fi 
} | if [ "${mailroot}" = "true" ]
    then
      mailx -s "${subject}" ${to}
    else
      while read line
      do
        echo "$line"
      done
    fi

chris@mimsy.UUCP (Chris Torek) (05/12/89)

In article <5520003@hplsla.HP.COM> dans@hplsla.HP.COM (Dan Siler) writes:
[large chunks of shell script deleted]
>  for i in $junkfiles
>  do
>    echo "removing any $i junk files..."
>    find / -name $i -exec rm {} \;
>  done

If you have anything other than a tiny file system, it is much faster
to run a single `find' that removes `junk' rather than several separate
`find's.  E.g.:

	pat=`echo -n -name; echo $junkfiles | sed -e 's/ / -o -name /'"
	find / \( $pat \) -exec /bin/rm {} \;

(the assignment to `pat' above can be deleted in the obvious manner);
or just write it directly.  This is the script we run each night:

find / \(	\( -name '#*'			-atime +1 \)	\
	-o	\( -name ',*'			-atime +1 \)	\
	-o	\(	\( -name '*.bak'			\
			-o -name '*.dvi'			\
			-o -name '*.CKP'			\
			-o \(					\
				  -name '*~'			\
				! -name 'Mail.help.~' \)	\
			-o -name '.*.bak'			\
			-o -name '.*.CKP'			\
			-o -name '.*~' \)	-atime +3 \)	\
	-o	\( -name '.emacs_[0-9]*'	-atime +7 \)	\
	-o	\( -name core				  \)	\
\) -print -exec /bin/rm -f {} \; > /tmp/.cleanup 2>&1
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris