Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I am trying to remove all files that have a hexadecimal digit in the first two digits, so I am using the following expression:

ls | grep -Z '^[0-9a-f][0-9a-f]' | xargs -0 rm

However, the terminal outputs the error:

xargs: argument line too long

To double-check, I ran:

ls | grep -Z '^[0-9a-f][0-9a-f]' 

which outputs all of the files that I want to delete.

Why am I getting this error? Additionally, how can I delete these files?

Also, my file names are similar to the following:


Perhaps the file names themselves are too long for xargs?

share|improve this question

4 Answers 4

up vote 5 down vote accepted

-Z is to output a NUL after each file name with grep -l, not to change the newlines to NULs in the lines it outputs. So xargs -0 sees only one huge record (with several newline characters in it) as there's no NUL delimited, so that's only one argument to pass to rm and it probably is bigger than the maximum size of an argument (128kB on Linux) and anyway there's no such file called ...ffd7ba85b0577b90c0fb1b3922303c486127d4<newline>...fff0b6886aff6cb4073742fbf7bcc1b47d9b45.

Simply do:

rm [0-9a-f][0-9a-f]*

Or if the list is too big:

printf '%s\0' [0-9a-f][0-9a-f]* | xargs -r0 rm

Or with zsh:

autoload zargs        # best in ~/.zshrc
setopt extendedglob   # ditto

zargs [0-9a-f](#c2)* -- rm

Or with ksh93:

command -x rm {2}([0-9a-f])*


find . ! -name . -prune -name '[0-9a-f][0-9a-f]*' -exec rm {} +

Beware that in non-C locales [a-f] may match more than [abcdef].

share|improve this answer
Only 5 solutions, pfft. – krowe Aug 19 '14 at 1:39

I'd suggest changing your selection of commands to something like:

 find . -name '^[0-9a-f][0-9a-f]' -print0 | xargs -0 rm

or another alternative

 find . -name '^[0-9a-f][0-9a-f]' -exec rm {} \;
share|improve this answer
There's no point using the non-standard -print0/xargs -0 over the standard -exec {} +. No point using -exec rm {} \; either as rm can take more than one argument. What goes after -name is a file name pattern, not a regexp. Some find implementations support a -regex, but the match is on the full path and is anchored already. – Stéphane Chazelas Aug 19 '14 at 6:09

You'd be better off using just find. Something like find -type f -iname '[0-9a-f][0-9a-f]*' -delete should do it. try first with -print instead of -delete to be sure, of course.

share|improve this answer
If you take a look at the accepted answer you'll see why this suggestion regarding xargs couldn't have worked. – roaima Apr 24 at 15:48
Got it and removed it from my answer. – spuk Apr 24 at 16:07

You may be running up against a file name limit depending on your file system type. See:

Specifically, the section on "Limits"

You can check your file system type if you dont know it using:

$ cat /etc/fstab

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.