[comp.unix.shell] Can U pipe filenames to rm???

greiner@col.hp.com (Mike Greiner) (09/28/90)

                    Piping filenames to the rm command???

I am trying to write a script to uninstall files installed via an
ninstall package.  I can generate a list of filenames to delete, but
I haven't figured out how to pipe this list of names to rm.  Here's
the heart of my script so far, followed by its output:

    ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4

Now I want to pipe the output of this command into rm.  Here's the output:

     /usr/local/doc/ninstall/UserGuide.mm
     /usr/local/man/man1/ninstall.1
     /usr/local/man/man1m/installd.1m

There may be a pretty simple solution to this, but I haven't found it.  I'm
considering using a for-loop that parses each line as the loop counter, 
but don't know if that's the best approach...appreciate any suggestions!

--Mike

#############################
# Mike Greiner              #
# Information Technology    #
# Hewlett-Packard           #
# Colorado Springs Division #
# greiner@col.hp.com        #
#############################

rickert@mp.cs.niu.edu (Neil Rickert) (09/29/90)

In article <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:
>
>                    Piping filenames to the rm command???
>
>I am trying to write a script to uninstall files installed via an
>ninstall package.  I can generate a list of filenames to delete, but
>I haven't figured out how to pipe this list of names to rm.  Here's
>the heart of my script so far, followed by its output:
>
>    ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4

 What is wrong with:

    rm `ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4`

-- 
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
  Neil W. Rickert, Computer Science               <rickert@cs.niu.edu>
  Northern Illinois Univ.
  DeKalb, IL 60115.                                  +1-815-753-6940

greiner@col.hp.com (Mike Greiner) (09/29/90)

Thanks to all who emailed me the solution to this problem!  For the 
benefit of anyone who might be curious, here's one answer:

ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4 | xargs rm
                                                         ^^^^^^^^^^
The xargs utility passes the input lines to the rm command as
parameters--just what I was after.  Thanks again!

--Mike

#############################
# Mike Greiner              #
# Information Technology    #
# Hewlett-Packard           #
# Colorado Springs Division #
# greiner@col.hp.com        #
#############################

cpcahil@virtech.uucp (Conor P. Cahill) (09/29/90)

In article <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:
>
>                    Piping filenames to the rm command???
>
>I haven't figured out how to pipe this list of names to rm. 

You don't need to.  Pipe the list of names to  xargs rm.


>    ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4

Just change this to:

     ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4 | xargs rm

This, of course, assumes you have xargs.  If you don't, you can get one 
of the PD versions that have been posted to c.s.u in the past.

Otherwise, if you know that the length of the list is relatively short (i.e.
it wont overrun the command line buffer length) you can do the following:

     rm `ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4`

else you could do the following:

     ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4 | while read name
     do
         rm $name
     done

-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

kimcm@diku.dk (Kim Christian Madsen) (09/29/90)

greiner@col.hp.com (Mike Greiner) writes:


>                    Piping filenames to the rm command???

>    ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4

>There may be a pretty simple solution to this, but I haven't found it.  I'm
>considering using a for-loop that parses each line as the loop counter, 
>but don't know if that's the best approach...appreciate any suggestions!

If you're sure the output of the ninstall does not exceed the limit of
what the shell you're using can handle (Bourne shell usually 5Kbytes),
you can use the following approach:

	ninstall .... | xargs rm

However, if the filelist from ninstall et al. does exceed the shell buffer
limit you can do something like (assuming Bourne shell):

	ninstall |
	while read filename
	do
		rm $filename
	done

					Kim Chr. Madsen

dylan@ibmpcug.co.uk (Matthew Farwell) (09/29/90)

In article <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:
>
>                    Piping filenames to the rm command???
>There may be a pretty simple solution to this, but I haven't found it.  I'm
>considering using a for-loop that parses each line as the loop counter, 
>but don't know if that's the best approach...appreciate any suggestions!

See xargs. (if you have it on your system.)

Example of how it works:

find / -name 'core' -print | xargs rm

Dylan.
-- 
Matthew J Farwell                 | Email: dylan@ibmpcug.co.uk
The IBM PC User Group, PO Box 360,|        ...!uunet!ukc!ibmpcug!dylan
Harrow HA1 4LQ England            | CONNECT - Usenet Access in the UK!!
Phone: +44 81-863-1191            | Sun? Don't they make coffee machines?

cpcahil@virtech.uucp (Conor P. Cahill) (09/29/90)

In article <1990Sep28.211655.4903@mp.cs.niu.edu> rickert@mp.cs.niu.edu (Neil Rickert) writes:
>In article <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:
>>
>>    ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4
>
> What is wrong with:
>
>    rm `ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4`

The fact that you are limited in the number of files and cumulative length of
the names of the files.  If you come up with one extra name, or one too many
characters in the names, the shell will refuse to exec it, saying something
about "arg list too long".


-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

cpcahil@virtech.uucp (Conor P. Cahill) (09/29/90)

In article <1990Sep29.001151.11544@diku.dk> kimcm@diku.dk (Kim Christian Madsen) writes:
>
>If you're sure the output of the ninstall does not exceed the limit of
>what the shell you're using can handle (Bourne shell usually 5Kbytes),
>you can use the following approach:
>
>	ninstall .... | xargs rm

No.  xargs was specifically written to handle the argument count and length
limits for command executions.  What it will do is run the rm command
multiple times (each with the maximum number of arguments that do not
exceed the limitations).



-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

davidsen@sixhub.UUCP (Wm E. Davidsen Jr) (09/30/90)

In article <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:

| Now I want to pipe the output of this command into rm.  Here's the output:

  I think what you want is the xargs routine, which may not be available
on your system but is on most.

Example:
  find {{stuff here}} -print | xargs rm -f
-- 
bill davidsen - davidsen@sixhub.uucp (uunet!crdgw1!sixhub!davidsen)
    sysop *IX BBS and Public Access UNIX
    moderator of comp.binaries.ibm.pc and 80386 mailing list
"Stupidity, like virtue, is its own reward" -me

mday@iconsys.uucp (Matt Day) (10/01/90)

In article <1977@sixhub.UUCP> davidsen@sixhub.UUCP (bill davidsen) writes:
>In article <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:
>> Now I want to pipe the output of this command into rm.  Here's the output:
>
>  I think what you want is the xargs routine, which may not be available
>on your system but is on most.
>
>Example:
>  find {{stuff here}} -print | xargs rm -f

Locally, we've hacked our "find" to handle:

	$ find . -name \*.old -rm

And "find" will do the unlink() itself.  It also has similar "-chown" and
"-chgrp".  It's much faster than running "rm" a zillion times..
-- 
- Matthew T. Day, Sanyo/Icon, mday@iconsys.icon.com || uunet!iconsys!mday

Harald.Eikrem@elab-runit.sintef.no (10/01/90)

Now, long before xargs I used this little simple utility:      --Harald E


/* rmf.c - Removes files according to contents of file arg or stdin */
#include <stdio.h>
int errno;

main(ac,av) char **av;
{
	char filen[BUFSIZ];
	if (ac > 1 && freopen(av[1], "r", stdin) == NULL) {
			perror(av[1]);
			fprintf(stderr, "usage: %s [ list-file ]\n\
Removes files according to contents of list-file (or standard input)\n\
one file per input line.\n", av[0]);
			exit(1);
	}
	while (gets(filen))
		if (unlink(filen) != 0) perror(filen);
}

sz@materna.uucp (Stefan Zimmermann) (10/01/90)

cpcahil@virtech.uucp (Conor P. Cahill) writes:

>In article <1990Sep28.211655.4903@mp.cs.niu.edu> rickert@mp.cs.niu.edu (Neil Rickert) writes:
>>In article <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:
>>>
>>>    ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4
>>
>> What is wrong with:
>>
>>    rm `ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4`

>The fact that you are limited in the number of files and cumulative length of
>the names of the files.  If you come up with one extra name, or one too many
>characters in the names, the shell will refuse to exec it, saying something
>about "arg list too long".

Perhaps this:
	
	ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4 > tmpfile
	split -50 tmpsplit tmpfile
	for i in tmpsplit??
	do
		rm `cat $i`
	done

OK, it's not a solution for very very very long argument lists !!


	Stefan

peter@ficc.ferranti.com (Peter da Silva) (10/02/90)

In article <1990Sep29.001151.11544@diku.dk> kimcm@diku.dk (Kim Christian Madsen) writes:
> If you're sure the output of the ninstall does not exceed the limit of
> what the shell you're using can handle...

> 	ninstall .... | xargs rm

> However, if the filelist from ninstall et al. does exceed the shell buffer...

	ninstall .... | xargs rm

xargs will split the commandline into chunks the shell will handle.
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.   'U`
peter@ferranti.com

kimcm@diku.dk (Kim Christian Madsen) (10/02/90)

peter@ficc.ferranti.com (Peter da Silva) writes:

>In article <1990Sep29.001151.11544@diku.dk> I wrote:
>> If you're sure the output of the ninstall does not exceed the limit of
>> what the shell you're using can handle...

>> 	ninstall .... | xargs rm

>> However, if the filelist from ninstall et al. does exceed the shell buffer...

>	ninstall .... | xargs rm

>xargs will split the commandline into chunks the shell will handle.

Sorry for the misunderstanding that I confused by saying that xargs is
limited by the shell buffer size... However, I have run across a version
of xargs that exactly does what it isn't supposed to do: take stdin in one
chunk and if it doesn't fit -- too bad.... And that's what triggered my
response, however the I suppose the remaining 99% of xargs will do the 
job nicely.

						Kim Chr. Madsen

george@hls0.hls.oz (George Turczynski) (10/04/90)

From previous postings-

> >Example:
> >  find {{stuff here}} -print | xargs rm -f
  
> Locally, we've hacked our "find" to handle:
> 	$ find . -name \*.old -rm

Our `find' (SunOS) supports the `-exec' option, and I assume this would be
fairly common.  So, those of you without xargs, and who | a. can't,  b. don't
want to | hack `find' use it like this:

	find {{stuff here}} -exec rm -f {} \;

Why use `xargs' when you don't need to ?

-- 
George P. J. Turczynski,   Computer Systems Engineer. Highland Logic Pty Ltd.
ACSnet: george@highland.oz |^^^^^^^^^^^^^^^^^^^^^^^^| Suite 1, 348-354 Argyle St
Phone:  +61 48 683490      |  Witty remarks are as  | Moss Vale, NSW. 2577
Fax:    +61 48 683474      |  hard to come by as is | Australia.
---------------------------   space to put them !    ---------------------------

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/05/90)

In article <941@hls0.hls.oz> george@hls0.hls.oz (George Turczynski) writes:
> 	find {{stuff here}} -exec rm -f {} \;
> Why use `xargs' when you don't need to ?

Speed.

---Dan

tif@doorstop.austin.ibm.com (Paul Chamberlain) (10/05/90)

In article <941@hls0.hls.oz> george@hls0.hls.oz (George Turczynski) writes:
>	find {{stuff here}} -exec rm -f {} \;
>Why use `xargs' when you don't need to ?

Perhaps an order of magnitude difference in speed/efficiency?
Besides the original question didn't specifically use "find."

Paul Chamberlain | I do NOT represent IBM.     tif@doorstop, sc30661 at ausvm6
512/838-7008     | ...!cs.utexas.edu!ibmaus!auschs!doorstop.austin.ibm.com!tif

dylan@ibmpcug.co.uk (Matthew Farwell) (10/05/90)

In article <941@hls0.hls.oz> george@hls0.hls.oz (George Turczynski) writes:
>From previous postings-
>
>> >Example:
>> >  find {{stuff here}} -print | xargs rm -f
>  
>> Locally, we've hacked our "find" to handle:
>> 	$ find . -name \*.old -rm
>
>Our `find' (SunOS) supports the `-exec' option, and I assume this would be
>fairly common.  So, those of you without xargs, and who | a. can't,  b. don't
>want to | hack `find' use it like this:
>
>	find {{stuff here}} -exec rm -f {} \;
>
>Why use `xargs' when you don't need to ?

2 points.
1) The original posting wasn't about find, it was about another pipe which
produced filenames on stdout, so comments on xargs were required.

2) find / -exec rm -f {} \; spawns rm everytime it encounters a file
so its very slow and expensive, whereas xargs collects all the filenames
together, bundles them up into lines which won't exceed the system limit
and then spawns one job for all of those. Its much more environmentally
friendly.

Dylan.
-- 
Matthew J Farwell                 | Email: dylan@ibmpcug.co.uk
The IBM PC User Group, PO Box 360,|        ...!uunet!ukc!ibmpcug!dylan
Harrow HA1 4LQ England            | CONNECT - Usenet Access in the UK!!
Phone: +44 81-863-1191            | Sun? Don't they make coffee machines?

cpcahil@virtech.uucp (Conor P. Cahill) (10/06/90)

In article <941@hls0.hls.oz> george@hls0.hls.oz (George Turczynski) writes:
>	find {{stuff here}} -exec rm -f {} \;
>
>Why use `xargs' when you don't need to ?

Because it is *******MUCH******* faster (assuming you are going to exec the
command more than once or twice).

-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

guy@auspex.auspex.com (Guy Harris) (10/06/90)

>Our `find' (SunOS) supports the `-exec' option, and I assume this would be
>fairly common.

It dates back to V6 or earlier; any "find" worthy of the name supports
"-exec".

bob@wyse.wyse.com (Bob McGowen x4312 dept208) (10/06/90)

In article <941@hls0.hls.oz> george@hls0.hls.oz (George Turczynski) writes:
>From previous postings-
>
>> >Example:
>> >  find {{stuff here}} -print | xargs rm -f

...deleted examples and discourse

>Why use `xargs' when you don't need to ?

Because the -exec for find will run the rm on a file by file basis.
If you find many matches to the pattern you have the overhead and
system load generated by an exec of rm for each file found.  Using
xargs can reduce the number of execs quite a bit and so would be
useful where you expect lots of files found or on a system with
heavy 24 hour usage.  In other cases, you would certainly not need
it, as you note.

Bob McGowan  (standard disclaimer, these are my own ...)
Product Support, Wyse Technology, San Jose, CA
..!uunet!wyse!bob
bob@wyse.com

jeff@onion.pdx.com (Jeff Beadles) (10/06/90)

In <28790001@col.hp.com> greiner@col.hp.com (Mike Greiner) writes:

>                    Piping filenames to the rm command???

>I am trying to write a script to uninstall files installed via an
>ninstall package.  I can generate a list of filenames to delete, but
>I haven't figured out how to pipe this list of names to rm.  Here's
>the heart of my script so far, followed by its output:

>    ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4

>Now I want to pipe the output of this command into rm.  Here's the output:

>     /usr/local/doc/ninstall/UserGuide.mm
>     /usr/local/man/man1/ninstall.1
>     /usr/local/man/man1m/installd.1m

>There may be a pretty simple solution to this, but I haven't found it.  I'm
>considering using a for-loop that parses each line as the loop counter, 
>but don't know if that's the best approach...appreciate any suggestions!

Well, a couple simple ways that will work most everywhere...

 1)  rm -f `ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4`

 2)  ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4 | sh rm -f

 3)  ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4 | xargs rm -f

 4)  ninstall -h $1 -vvvvv -p $2 | grep path | cut -d " " -f4 | while read file
     ; do ; rm -f $file ; done


There are pitfalls with all.
	#1, #2, and #3 will all complain if there are no files to remove
	  if you don't use the "-f" flag.
	#1 will fail if there are too many files to delete, or the total size
	  of their pathnames is above a magic number.
	#3 requires xargs
	#2 and #4 are bourne shell specific.


Have fun!
	-Jeff
-- 
Jeff Beadles	jeff@onion.pdx.com

george@hls0.hls.oz (George Turczynski) (10/09/90)

I wrote...
> >Why use `xargs' when you don't need to ?

Finally, someone replies...

In article <1990Oct5.163050.8835@ibmpcug.co.uk>, dylan@ibmpcug.co.uk (Matthew Farwell) writes:

> 2 points.
> 1) The original posting wasn't about find, it was about another pipe which
> produced filenames on stdout, so comments on xargs were required.
> 
> 2) find / -exec rm -f {} \; spawns rm everytime it encounters a file
> so its very slow and expensive, whereas xargs collects all the filenames
> together, bundles them up into lines which won't exceed the system limit
> and then spawns one job for all of those. Its much more environmentally
> friendly.

1) That is correct.  To many articles are posted as advice that seem to require
   blind faith to use them.  For those of you who haven't caught on, the 
   question was rhetorical, looking for someone to respond.  I say the answer
   to it should have been in the posting that contained it.

   It's only a small gripe, but I'd just like to see people who answer (any)
   questions on the net answer thoroughly, ie with alternatives and pro's/con's
   of each.  People who can't answer like this probably shouldn't be answering.
   After all, a genius is not someone who can simply solve a problem, but
   someone who can solve in numerable ways.

   I'd like to see users of the net using methods we give them with reason, not
   blind faith.

2) This is also true, yet wasn't hinted at in the first article containing it,
   where it perhaps should have been.

   What is more environmentally friendly is bandwidth not being wasted by
   people reverberating questions like `why use xargs ?' all over the net,
   because someone posted answers requiring questions :-)

   Oh well, enough said, back to work...

-- 
George P. J. Turczynski,   Computer Systems Engineer. Highland Logic Pty Ltd.
ACSnet: george@highland.oz |^^^^^^^^^^^^^^^^^^^^^^^^| Suite 1, 348-354 Argyle St
Phone:  +61 48 683490      |  Witty remarks are as  | Moss Vale, NSW. 2577
Fax:    +61 48 683474      |  hard to come by as is | Australia.
---------------------------   space to put them !    ---------------------------