Override copy files using -exec cp - linux

mkdir zipFiles
find . -name '*.zip' -exec cp {} zipFiles/ \;
Error:
cp: ‘./zipFiles/status.zip’ and ‘zipFiles/status.zip’ are the same file
I tried these commands to force copy to override the existing files, but none of them works;
find . -name '*.zip' -exec cp {} zipFiles/ \;
find . -name '*.zip' -exec cp -f {} zipFiles/ \;
find . -name '*.zip' -exec cp -rf {} zipFiles/ \;
find . -name '*.zip' -exec cp {} -rf zipFiles/ \;

You don't want find to search zipFiles. One way to do that is
find . -name '*.zip' \( ! -path '*/zipFiles/*.zip' \) -exec cp {} zipFiles/ \;
To speed things up, use -exec ... + to let cp copy as many files at once as possible. Either
find . ... -exec sh -c 'cp "$#" zipFiles' _ {} +
or, if you are using GNU cp,
find . ... -exec cp -t zipFiles {} +

You can use the rsync command:
rsync SOURCE TARGET
or
rsync --force SOURCE TARGET

Related

How to find and rename a batch of files in linux

when using the following command:
find foo/bar -type f -name '*.txt' -execdir sh -c 'mv "$0" "new_prefix_${0}"' {}\;
I get the following error:
mv: cannot move './abc.txt' to 'new_prefix_./abc.txt': No such file or directory
The './' is the problem, how can I avoid this?
find foo/bar -type f -name '*.txt' -execdir sh -c 'mv "$0" "new_prefix_$(basename "$0")"' {} \;

How to remove files without certain extension?

How to remove all files without the .txt and .exe extensions recursively in the current working directory? I need a one-liner.
I tried:
find . ! -name "*.txt" "*.exe" -exec rm -r {} \
find -type f -regextype posix-extended -iregex '.*\.(txt|exe)$'
Try this.
find . -type f ! -name "*.exe" ! -name "*.txt" -exec rm {} \;
The above command will remove all the files other than the .exe and .txt extension files in the current directory and sub directory recursively.
If you have GNU find with the -delete action:
find . -type f ! \( -name '*.txt' -o -name '*.exe' \) -delete
And if not:
find . -type f ! \( -name '*.txt' -o -name '*.exe' \) -exec rm -f {} +
using -exec ... {} + to execute rm as few times as possible, with the arguments chained.
Try the following:
rm -f $(find . -type f ! \( -name "*.txt" -o -name "*.exe" \))
This will first recursively find all files that do not end with .txt or .exe extensions, and then delete all of these files.

How to delete multiple type of files?

I can delete .zip files using following command.
find . -type f -name '*.log.*.zip' -exec rm \{\} \;
Is it possible to delete .zip and .gz file at the same time ?
find . -type f -name '*.log.*.zip' | '*.log.*.gz' -exec rm \{\} \;
You can try like this using brace expansion:
$ rm -rf log.{zip,gz}

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

Loop Over Directories, Process files & Rename New Files

I'm writing a script that would loop over the sub-directories of a given directory, find for ".js" files, compiles with closure. I'm doing this with this commands:
find ./js/ -type f -name "*.js" -exec java -jar compiler.jar --compilation_level SIMPLE_OPTIMIZATIONS --js '{}' --js_output_file '{}'.compiled \;
And then removing the old ".js" files with:
find ./js/ -type f -name "*.js" | xargs rm -f
But, I can't rename the files with the names "foo.js.compiled" to "foo.js".
Please help. Thanks in advance.
Try
for i in `find . -type f -name "*.js.compiled"`; do mv $i ${i%.*} ; done
You can do something like:
find . -name "*.js.compiled" -exec rename -v 's/\.compiled$//' {} +
Test:
$ find . -name "foo*"
./fil/foo.js.compiled
$ find . -name "*.js.compiled" -exec rename -v 's/\.compiled$//' {} +
'./fil/foo.js.compiled' renamed to './fil/foo.js'
$ find . -name "foo*"
./fil/foo.js
use the following code:
find ./js/ -name "*.js.compiled" -print0 | while read -r -d '' filename; do
mv "$filename" "${filename/js.compiled/js}";
done

Resources