DEV Community

Cover image for Execute commands on 'find' output ft. -exec and xargs
Mohamed Yahia
Mohamed Yahia

Posted on

Execute commands on 'find' output ft. -exec and xargs

How to run commands on files found

If I want to delete any log files in a directory and log files in this directory have common substring "log" in their name, we could do it all in one command.

nuclearegg69@zenbook-f13:~$ ls
1   2  a             b  colt-ex  empty  hello2   inNano3.txt    inNanoSymlink  testRen2      unsortedNums.txt  world2
1a  3  alphabet.txt  c  echo     hello  inNano3  inNanoRenamed  testRen        unsorted.txt  world
nuclearegg69@zenbook-f13:~$ find ~ -name "*hello*" -exec rm -r '{}' ';'
nuclearegg69@zenbook-f13:~$ ls
1   2  a             b  colt-ex  empty    inNano3.txt    inNanoSymlink  testRen2      unsortedNums.txt  world2
1a  3  alphabet.txt  c  echo     inNano3  inNanoRenamed  testRen        unsorted.txt  world
nuclearegg69@zenbook-f13:~$
Enter fullscreen mode Exit fullscreen mode

OR

nuclearegg69@zenbook-f13:~$ ls
1   2  a             b  colt-ex  empty  hello2   inNano3.txt    inNanoSymlink  testRen2      unsortedNums.txt  world2
1a  3  alphabet.txt  c  echo     hello  inNano3  inNanoRenamed  testRen        unsorted.txt  world
nuclearegg69@zenbook-f13:~$ find . -name "*hello*" | xargs rm -r
nuclearegg69@zenbook-f13:~$ ls
1   2  a             b  colt-ex  empty    inNano3.txt    inNanoSymlink  testRen2      unsortedNums.txt  world2
1a  3  alphabet.txt  c  echo     inNano3  inNanoRenamed  testRen        unsorted.txt  world
Enter fullscreen mode Exit fullscreen mode

Let's break those commands apart starting with the first one:

  • find: used to find objects (files, dirs, links)
  • ~ : in home directory
  • -name: with a name of
  • "*hello*": containing substring hello (i.e. with zero or more characters before 'hello' and zero or more after)
  • -exec: execute following operation/command on every record found
  • rm -r: delete recursively (so dir and all dirs and files nested within it)
  • '{}' placeholder for current file/dir (so rm -r '{}' = delete current file/dir and it will run for every file/dir found)
  • ';' : indicate the end of the rm command and is passed as a parameter to dir to not confuse the bash that it ends the whole find command

'{}' since this is a placeholder for current file name, it provides a convenient way for renaming files

find . -type f -exec mv '{}' '{}_new' ';'
Enter fullscreen mode Exit fullscreen mode

This adds a substring _new at the end of each file name

  • xargs: the pipe passes the list of files found to xargs standard input and xargs runs the command following it on each file, passing the file as an argument

Top comments (0)