Asked  7 Months ago    Answers:  5   Viewed   43 times

I have several hundred PDFs under a directory in UNIX. The names of the PDFs are really long (approx. 60 chars).

When I try to delete all PDFs together using the following command:

rm -f *.pdf

I get the following error:

/bin/rm: cannot execute [Argument list too long]

What is the solution to this error? Does this error occur for mv and cp commands as well? If yes, how to solve for these commands?

 Answers

64

The reason this occurs is because bash actually expands the asterisk to every matching file, producing a very long command line.

Try this:

find . -name "*.pdf" -print0 | xargs -0 rm

Warning: this is a recursive search and will find (and delete) files in subdirectories as well. Tack on -f to the rm command only if you are sure you don't want confirmation.

You can do the following to make the command non-recursive:

find . -maxdepth 1 -name "*.pdf" -print0 | xargs -0 rm

Another option is to use find's -delete flag:

find . -name "*.pdf" -delete
Tuesday, June 1, 2021
 
Joegramming
answered 7 Months ago
66

Your full code is:

rm -f /tmp/temp.files
ls -1 /var/log/processing/*.log | xargs -n1 basename > /tmp/temp.files
cat /tmp/temp.files | sed -r "s~(.*)-[0-9]{4}(-[0-9]{2})+.log~cat /var/log/processing/1* >> /var/log/processing/1$(date  +"-%Y-%m-%d-%H-%M").log~" | uniq | sh
cd /var/log/processing
xargs rm -rf < /tmp/temp.files
rm -f /tmp/temp.files

But the problem lies on the ls -1 /var/log/processing/*.log part, so I am skipping the rest.

The expansion done by /var/log/processing/*.log gives so many results that ls itself cannot handle all of them and hence prints the "Argument list too long" message.

You can use a find statement like this:

find /var/log/processing -name "*.log" -exec basename {} ; > /tmp/temp.files

See I am not using ls parsing (read interesting Why you shouldn't parse the output of ls).

Friday, August 20, 2021
 
GilShalit
answered 4 Months ago
98

The common way to handle situations like this is to check if the standard input stream is connected to a terminal or not, using isatty or similar functions depending on your OS. If it is, you take parameters from the command line, if not (it's been redirected), you read standard input.

Friday, August 27, 2021
 
pthesis
answered 4 Months ago
64

Use find

find /home/*/public_html -type f -exec grep -l 'pattern' {} +

The + modifier makes it group the filenames in manageable chunks.

However, you can do it with grep -r. The arguments to this should be the directory names, not filenames.

grep -rl 'pattern' /home/*/public_html

This will just have 500+ arguments, not thousands of filenames.

Thursday, September 9, 2021
 
ericj
answered 3 Months ago
15

A main function is defined like this:

int main (int argc, char *argv[])

or

int main (int argc, char **argv)

As I understand it, argc = Argument Count and argv = Argument Vector. argc is the number of arguments (you can choose how many), and argv contains that number of arguments, which contain all the actual data you want to pass in to your program from the command line. But remember there is always at least one argument which comes first: The name of the program.

These are not used during compilation but during run time. Running the program is different from compiling and linking, which have to be done first (using gcc, in your case).

Wednesday, October 27, 2021
 
Ulrich
answered 1 Month ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share