You are not logged in.

#1 2016-01-05 19:04:00

macaco
Member
From: Graz, Austria
Registered: 2009-03-22
Posts: 101

[SOLVED] find | grep | xargs rm

As I want to delete all the hidden files from my music dir I came up with the following pipe:

find Música/* | egrep -Z \/\\. | xargs -0 rm

It did not work and the output was "File name too long". A funny thing is, by the way, that I needed two "\" in order to mark the "." as a literal character.


However if I do

find Música/* | egrep -Z \/\\. | xargs -0 echo

I get a nice list of files with correct lines separation.

What did I do wrong?

Last edited by macaco (2016-01-06 08:49:26)

Offline

#2 2016-01-05 19:20:36

ewaller
Administrator
From: Pasadena, CA
Registered: 2009-07-13
Posts: 19,791

Re: [SOLVED] find | grep | xargs rm

I'm guessing three issues.  First, what will happen to hidden directories that have non-hidden files in them?  Second, what happens when there is a space in the name of a file?  Third, what happens if there are characters in the file name that have special meaning to the shell? For example, [,],(,),*,/,.,?,',"    ?


Nothing is too wonderful to be true, if it be consistent with the laws of nature -- Michael Faraday
Sometimes it is the people no one can imagine anything of who do the things no one can imagine. -- Alan Turing
---
How to Ask Questions the Smart Way

Offline

#3 2016-01-05 19:23:13

alphaniner
Member
From: Ancapistan
Registered: 2010-07-12
Posts: 2,810

Re: [SOLVED] find | grep | xargs rm

I can't explain your problem, but there's a better way to do this: use find's -exec flag.

First, it's good practice to use it with ls to see everything it locates:

find Música/* -type f -name ".*" -exec ls -l {} \;

After you confirm you actually want to delete everything:

find Música/* -type f -name ".*" -exec /usr/bin/rm -i {} \;

I put a -i in the rm command just to be on the safe side, it's up to you to remove it if you want.


But whether the Constitution really be one thing, or another, this much is certain - that it has either authorized such a government as we have had, or has been powerless to prevent it. In either case, it is unfit to exist.
-Lysander Spooner

Offline

#4 2016-01-05 19:28:29

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,424
Website

Re: [SOLVED] find | grep | xargs rm

Why not use find's pattern matching?

find . -name ".*?" -exec rm {} \;

Not a Sysadmin issue, moving to Scripting...


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#5 2016-01-05 19:37:57

brebs
Member
Registered: 2007-04-03
Posts: 3,742

Re: [SOLVED] find | grep | xargs rm

Er, find has a "-delete" option - simplest and safest.

Offline

#6 2016-01-05 21:07:46

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,530
Website

Re: [SOLVED] find | grep | xargs rm

While -delete would be best, just as an added teaser to read the man page: "-exec rm -i {}" could also be replaced with "-ok rm {}".


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#7 2016-01-05 21:43:48

fukawi2
Ex-Administratorino
From: .vic.au
Registered: 2007-09-28
Posts: 6,224
Website

Re: [SOLVED] find | grep | xargs rm

macaco wrote:
find Música/* | egrep -Z \/\\. | xargs -0 rm

....
What did I do wrong?

To answer your original question, you have told xargs to use the NUL character as a separator (the -0 flag) but your find command isn't outputting NUL delimited data. So xargs is passing the entire output to a single invocation of rm, which evidentially does not like such a long input.

Use one of the solutions others have posted -- there is no need for any piping here, and especially no need for grep in the middle.

EDIT: your use of the -Z flag to grep isn't working quite how you expect. It does NUL delimit file name output, but in this context grep isn't outputting file names, it is outputting a string of data that just happens to be file names (but grep doesn't know they are filenames) so it doesn't insert any NUL characters.

Last edited by fukawi2 (2016-01-05 21:45:53)

Offline

#8 2016-01-05 22:04:10

progandy
Member
Registered: 2012-05-17
Posts: 5,193

Re: [SOLVED] find | grep | xargs rm

If you really need egrep, then you need the --null-data (small -z) option and find with -print0

find ... -print0 | egrep -z ... | xargs -0 -n1 echo "Match:"

Last edited by progandy (2016-01-05 22:04:26)


| alias CUTF='LANG=en_XX.UTF-8@POSIX ' |

Offline

#9 2016-01-06 08:48:59

macaco
Member
From: Graz, Austria
Registered: 2009-03-22
Posts: 101

Re: [SOLVED] find | grep | xargs rm

fukawi2 wrote:
macaco wrote:
find Música/* | egrep -Z \/\\. | xargs -0 rm

....
What did I do wrong?

To answer your original question, you have told xargs to use the NUL character as a separator (the -0 flag) but your find command isn't outputting NUL delimited data. So xargs is passing the entire output to a single invocation of rm, which evidentially does not like such a long input.

Use one of the solutions others have posted -- there is no need for any piping here, and especially no need for grep in the middle.

EDIT: your use of the -Z flag to grep isn't working quite how you expect. It does NUL delimit file name output, but in this context grep isn't outputting file names, it is outputting a string of data that just happens to be file names (but grep doesn't know they are filenames) so it doesn't insert any NUL characters.

Thank you man!!! This really made me a little bit wiser smile

For the time being I used

find Música/* -type f -name ".*" -exec /usr/bin/rm -i {} \;

which solved the problem.

Guess I can close this thread as solved now.

Last edited by macaco (2016-01-06 09:25:32)

Offline

Board footer

Powered by FluxBB