Linux find xargs rm

How to delete directories based on `find` output?

How could I process all these lines with rm -fr in order to delete the directories and their content?

@SuperChafouin but will not work for paths with spaces in them (hence using -exec with quoted «<>» ).

9 Answers 9

Find can execute arguments with the -exec option for each match it finds. It is a recommended mechanism because you can handle paths with spaces/newlines and other characters in them correctly. You will have to delete the contents of the directory before you can remove the directory itself, so use -r with the rm command to achieve this.

For your example you can issue:

You can also tell find to just find directories named .svn by adding a -type d check:

find . -name ".svn" -type d -exec rm -r "<>" \; 

Warning Use rm -r with caution it deletes the folder and all its contents.

If you want to delete just empty directories as well as directories that contain only empty directories, find can do that itself with -delete and -empty :

find . -name ".svn" -type d -empty -delete 

I have seen advice to always run -type after -name in find commands, since calls to stat to get the type are expensive. I just tried it myself on a fairly large bunch of files, and it seems to be true: running find . -name ‘foo’ -type d took 19 secs, while find . -type d -name ‘foo’ took 32 secs. So about 50% longer time to run -type first.

i’ve been using this command for years, but on Mac now i get errors saying those directories do not exist. Even though it does delete them. I never saw messages before.

@chovy @clément That is because find wants to see in that folder for other matches, while it’s removing the folder at the same time. ~I don’t know yet how to fix this.~ Dirty fix: find . -name «folder-to-delete» -print0 | xargs -r0 — rm -r

@chovy @Clément I think the -depth argument fixes this: find . -depth -name «.svn» -type d -exec rm -r «<>» \;

Here is a portable still faster than the accepted answer way.

Using a + instead of a semicolon as find command terminator is optimizing the CPU usage. That can be significant if you have a lot of .svn sub-directories:

find . -name .svn -type d -exec rm -rf <> + 

Note also that you never 1 need to quote the curly braces here.

1 Unless you use the fish shell (this might have been fixed since I wrote this reply).

@ShichengGuo With the semicolon, there will be one rm command per directory found, with the + a single rm command will process all directories found (or at least a very large number of them.) I don’t get your second question, curly braces are used here.

I think @ShichengGuo means why don’t we need to quote the curly braces here (@jlliagre wrote that we never need to quote them). I can’t find a reference now, but I understand it’s because find will automatically escape the paths replaced for <>.

Читайте также:  Astra linux kernel version

@gaoithe I did rollback you edit which replaced a correct statement with an incorrect one. Using + does reduce CPU usage, Using ; does not lead to a command too long error.

Assume you are using gnu find, you can use the -delete option:

which is easier to remember.

Consider expanding your post with an explanation of the command (or documentation to back up your solution). Often one (or two) line answers are not the most illuminating.

The options order is very important, find will execute them in order so, -delete have to be the last one

A faster way to do this is:

find . -name ".svn" -type d -prune -exec rm -rf '<>' '+' 

In case you have «.svn» inside another «.svn».

On my computer when I use:

find . \( -name dirname -type d \) -exec rm -r '<>' ';' 

The directories are deleted but I get the error:

find: ‘./dirname’: No such file or directory 

My directories aren’t empty, so the -delete option won’t work for me. I found the reason for this behavior here:

  1. find takes (not necessarily) the first entry in the ./ directory. this would be e.g. dir.1/
  2. it compares it to the pattern ‘dir.?’. does it match? yes.
  3. find executes «rm -r dir.1».
  4. find tries to enter dir.1/ to find the pattern within the directory. it doesn’t know anything about the exec command.
  5. it doesn’t find dir.1/ anymore. returns ENOENT (look at the strace output)

I used this instead to work around:

rm -r `find . -name dirname -type d` 

Keep in mind that find will still try to recurse into directories named dirname, which isn’t really necessary and will take some additional time. Depending on your directory structure, you might be able to work around this with the —depth find option. In addition, if you have a directory structure like dirname/foo/dirname you will get «No such file or directory» errors from rm. To suppress the errors you can redirect stderr to /dev/null or use the -f (force) flag with rm.

Источник

How To Use xargs With Find in Linux

After reading this tutorial, you can search files using the find command and execute a specific command based on matched results.

Instructions and examples are helpful for most Linux distributions. The content is optimized both for new and experienced Linux users.

All steps described in this article contain screenshots to make it easy for all Linux users to understand and apply them.

Usage examples included in this article are the following:

  • Find and delete files by extension (File type).
  • Find and delete files by name.
  • Find and change file permissions based on current permissions.

Brief Introduction To Find and xargs Commands

The xargs command, when combined with other commands like find, uses the output of the first command as an argument.

For example, let’s run the find command to identify files with a specific extension or file type. We can add the xargs command to execute an action for all files matching the extension specified to find.

As you can see in the following line, a pipe separates COMMAND 1 and COMMAND 2, where COMMAND 1 may be any command like ls, and COMMAND 2, including the xargs command, followed by a specific action like cat.

The applicable example would be:

This command will list all files within the current directory. Then the output (listed files) will be used by xargs as an argument, and their content will be printed as instructed by xargs cat. See the following screenshot:

Читайте также:  Изменить разрешение экрана linux терминал

How To Find and Move Files Using xargs

The first section of this tutorial explains how to use find and xargs commands to search and move files matching a condition, in this case, the file type.

Let’s begin by finding files by extension and moving them to a specific directory using xargs.

Before beginning, run the ls command to show files and directories within my subdirectory named testdir.

As you can see, there are different file types, including .txt, .c, and files without extensions. Also, pay attention to the tutorialdir directory.

Let’s assume you want to move files with a specific extension to a directory. The syntax is the following:

In the previous syntax, the -name option precedes the file name or condition based on the file name. The type f option specifies that the find command deals with files and not directories. The -t option previous to the destination directory is used to define the target directory. Pay attention to the wildcard (*) previous to the extension, instructing the command find to search all files of the specified extension independently of the name.

Thus, if you want to move all .txt files to the directory named tutorialdir, execute the following command:

As you can see, after running the ls command twice, the files were moved from the current directory to the tutorialdir subdirectory.

The syntax is the same for all file types. Let’s repeat it, this time for .c files:

The first ls command shows three .c files in the current directory. After running the find command with xargs, the tree command shows all .c files were moved to the tutorialdir directory, where .txt files were carried in the previous example.

Find and Delete Files and Directories by Name With xargs

The syntax to find and delete files using xargs is the following:

This is where is the parent directory you search files, and is the name of the file you want to find and remove.

Let’s see the current scenario in the following screenshot:

In the first example, choose files by type, as done in the previous section, to remove them, as shown below:

As you can see above, all .c files were successfully deleted.

Now, the scenario is the following:

In the current example, I will use the wildcard to remove all files whose name starts with “file”, independently of the name continuation.

Until now, this article explained how to deal with files. Now, let’s see how to use find and xargs with directories. In the new scenario, there are five new directories: dir1, dir2, dir3, dir4, and dir5, as shown in the following image:

Assuming you want to remove all directories with names starting with “dir”, run the same command. However, after the rm command, add the -r flag used to deal with directories, as shown in the following figure:

Find and Delete Files Based on Permissions

This section describes finding files by specific permissions and changing them using xargs.

As you can see below, files something1.txt, something2.txt, and something3.txt have full permissions for everyone (777).

The syntax to find files by permission and change them is shown below:

To find all files with full permissions to everyone (777) in the current directory and change them to full permissions for the owner and read and execute permissions for group users and others (755), run the command executed in the following:

Читайте также:  Sony playstation linux emulator

Conclusion

As you can see, the xargs command, when combined with the find command, is handy for bulk tasks or specific tasks when you don’t know a file location. Both commands are easy to implement and can be incorporated by new users to ease their experience with the Linux terminal. Find and xargs are basic Linux commands any Linux user must know how to apply. Xargs can be combined with other basic commands like ls. The instructions explained above are helpful for all Linux distributions.

Check out more articles for more Linux tips and tutorials.

About the author

David Adams

David Adams is a System Admin and writer that is focused on open source technologies, security software, and computer systems.

Источник

Delete a list of files with find and grep

I want to delete all files which have names containing a specific word, e.g. «car». So far, I came up with this:

12 Answers 12

or pass the output of your pipeline to xargs :

find | grep car | xargs rm -f 

Note that these are very blunt tools, and you are likely to remove files that you did not intend to remove. Also, no effort is made here to deal with files that contain characters such as whitespace (including newlines) or leading dashes. Be warned.

+1. But on the first few runs: change «rm» to «echo rm» . and verify that it only outputs file you really want to delete, and no others ^^

@nhahtdh: xargs: illegal option — d ; all the world is not LInux. And what about directories that contain \n in their name? If you worry about whitespace, you should use find —print0 . xargs -0

Please be aware that this will not work if your files contain unusual characters (like spaces) or start with a dash. Please see my answer for a fix.

To view what you are going to delete first, since rm -fr is such a dangerous command:

find /path/to/file/ | grep car | xargs ls -lh 

Then if the results are what you want, run the real command by removing the ls -lh , replacing it with rm -fr

find /path/to/file/ | grep car | xargs rm -fr 

It does exactly what you ask, logically running rm -rf on the what grep car returns from the output of find . which is a list of every file and folder recursively.

You really want to use find with -print0 and rm with — :

find [dir] [options] -print0 | grep --null-data [pattern] | xargs -0 rm -- 

A concrete example (removing all files below the current directory containing car in their filename):

find . -print0 | grep --null-data car | xargs -0 rm -- 
  • -print0 , —null-data and -0 change the handling of the input/output from parsed as tokens separated by whitespace to parsed as tokens separated by the \0 -character. This allows the handling of unusual filenames (see man find for details)
  • rm — makes sure to actually remove files starting with a — instead of treating them as parameters to rm . In case there is a file called -rf and do find . -print0 | grep —null-data r | xargs -0 rm , the file -rf will possibly not be removed, but alter the behaviour of rm on the other files.

Источник

Оцените статью
Adblock
detector