The find Command with -exec Does Not Run the -exec Command - linux

I want to write a simple command to cleanup my project files, so I used:
find . -type f -name "*.o" -o -name "*.a" -o -name "*.ko" -exec rm '{}' +
Oddly it didn't work. And when I removed " -exec rm '{}' +" I could see that it dumped the files out the terminal, so it looks like my expression is correct. I even tried changing "'{}' +" to "'{}' \;", but this also didn't work. I also tried replacing rm with echo but nothing was displayed in the terminal. Am I doing something wrong?
Using Ubuntu 12.04.

Try using it like this:
find . -type f \( -name "*.o" -o -name "*.a" -o -name "*.ko" \) -exec rm -f {} \;
When using multiple files with find combined with exec it often only acts on the last filename.

Related

find and copy so files while removing all but major version number

Trying to use "find" to copy a bunch of shared objects. Almost there, but would like to remove all version numbers except the major version.
example would be somesharedobject.so.30.0.4 copied to somesharedobject.so.30
find . -maxdepth 1 -type f -name '*.so.*' -exec cp '{}' test/'{}' \;
I'm guessing I'm going to have to pipe to xargs and sed but just hitting a mental block.
find . -maxdepth 1 -type f -name '*.so.*'|xargs -I '{}' cp '{}' test/'{}'
Think I'm just going to go with something like this
find . -maxdepth 1 -type f -name '*.so.*' -exec cp '{}' test/'{}' \;
for f in test/*.so.* ; do mv "$f" "${f%.*.*}" ; done
seems to work ok from my tests
I would write a function + script to make the job easy
#!/bin/bash
specialised_copy(){
version="${1##*so.}"
# extract the version part alone in the above step
cp "$1" "test/${1%%.so*}.so.${version%%.*}"
#cut the major version part from the version and use it for copy
#note folder test should be relative to where the script is saved
}
export -f specialised_copy
find . -maxdepth 1 -type f -name '*.so.*' -exec bash -c 'specialised_copy "$1"' _ {} \;

linux find: move files by xargs

How should this be fixed? I am following a tutorial but I receive this error:
$ find ~/Desktop -name “*.jpg” -o -name “*.gif” -o -name “*.png” -print0 | xargs -0 mv –target-directory ~/Pictures
mv: cannot stat `–target-directory': No such file or directory
*I am interested on how to perform this command using xargs!
Using find and exec
$ find ~/Desktop -name "*.jpg" -exec mv '{}' /tmp/target/ \; -or -name "*.gif" -exec mv '{}' /tmp/target/ \; -or -name "*.png" -exec mv '{}' /tmp/target/ \;
Using xargs
$ find ~/Desktop -name "*.jpg" -or -name "*.gif" -or -name "*.png" | xargs -I SRCFILE mv SRCFILE /tmp/target/
You don't need to use xargs, find can execute commands on the matches:
find ~/Desktop -name “*.jpg” -o -name “*.gif” -o -name “*.png” -exec mv \{\} ~/Pictures \;
You can give a command after -exec and before the escaped semicolon \;. The \{\} is replaced with the matching file name.
From man find:
-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of ';' is encountered. The string '{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command, not just in arguments where it is alone, as in some versions of find. Both of these constructions might need to be escaped (with a '\') or quoted to protect them from expansion by the shell. See the EXAMPLES section for examples of the use of the -exec option. The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.
Notice that the semicolon and {} must be escaped.
I believe -target-directory should be --target-directory, or just -t.

How to write a unix command or script to remove files of the same type in all sub-folders under current directory?

Is there a way to remove all temp files and executables under one folder AND its sub-folders?
All that I can think of is:
$rm -rf *.~
but this removes only temp files under current directory, it DOES NOT remove any other temp files under SUB-folders at all, also, it doesn't remove any executables.
I know there are similar questions which get very well answered, like this one:
find specific file type from folder and its sub folder
but that is a java code, I only need a unix command or a short script to do this.
Any help please?
Thanks a lot!
Perl from command line; should delete if file ends with ~ or it is executable,
perl -MFile::Find -e 'find(sub{ unlink if -f and (/~\z/ or (stat)[2] & 0111) }, ".")'
You can achieve the result with find:
find /path/to/directory \( -name '*.~' -o \( -perm /111 -a -type f \) \) -exec rm -f {} +
This will execute rm -f <path> for any <path> under (and including) /path/to/base/directory which:
matches the glob expression *.~
or which has an executable bit set (be it owner, group or world)
The above applies to the GNU version of find.
A more portable version is:
find /path/to/directory \( -name '*.~' -o \( \( -perm -01 -o -perm -010 -o -perm -0100 \) \
-a -type f \) \) -exec rm -f {} +
find . -name "*~" -exec rm {} \;
or whatever pattern is needed to match the tmp files.
If you want to use Perl to do it, use a specific module like File::Remove
This should do the job
find -type f -name "*~" -print0 | xargs -r -0 rm

find command to find files and concatenate them

I am trying to find all the files of type *.gz and cat them to total.gz and I think I am quite close on this.
This is the command I am using to list all *.gzfiles:
find /home/downloaded/. -maxdepth 3 -type d \( ! -name . \) \
-exec bash -c "ls -ltr '{}' " \
How to modify it so that it will concatenate all of them and write to ~/total.gz
Directory structure under downloaded is as follows
/downloaded/wllogs/303/07252014/SysteOut.gz
/downloaded/wllogs/301/07252014/SystemOut_13.gz
/downloaded/wllogs/302/07252014/SystemOut_14.gz
Use cat in -exec and redirect output of find:
find /home/downloaded/ -type f -name '*.gz' -exec cat {} \; > output
Use echo in -exec and redirect the output:
find /home/downloaded/ -name "*.gz" -exec echo {} \; > output

How can I make find pass file names to exec without the leading directory name?

Someone created directories with names like source.c. I am doing a find over all the directories in a tree. I do want find to search in the source.c directory, but I do not want source.c to be passed to the grep I am doing on what is found.
How can I make find not pass directory names to grep? Here is what my command line looks like:
find sources* \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) -exec grep -Hi -e "ThingToFind" {} \;
Add -a -type f to your find command. This will force find to only output files, not directories. (It will still search directories):
find sources* \( -name "*.h" -o -name "*.cpp" -o -name "*.c" \) -a -type f -exec grep -Hi -e "ThingToFind" {} \;

Resources