Imagine a folder structure like this:
/411/folder1/
/411/archive/
/211/archive/
/211/folder1/
/211/folder2/
In each subfolder there will be files and more subfolders with files/folders. I'm interested in to zip all the files in the subfolders called 'archive' and ignore all other folders in the structure.
If I use the command: find * -type d -name 'archive'
The output will be like:
928/archive
973/archive
990/archive
What I'm interested in is to have an output like:
928/archive/file1.jpg
928/archive/file2.jpg
928/archive/folder1/file3.jpg
And so on so that I can use the commander: find * -type d -name 'archive' [with some more/other options] | zip all_archive_files.zip -#
How can this be done?
you can match on the whole path using -path or regex: for example
find . -regex './[0-9]+/archive/.*' -type f -exec zip all.zip {} \;
This is crude, but you could:
find . -type d -name 'archive' -exec find {} \; | zip stuff.zip -#
The normal way to run zip takes filenames from the command line and with the -r flag the command will recurse into directories by itself. Consider
find . -name 'archive' -type d -exec zip -r all_archive_files.zip {} +
The -exec option will run zip -r all_archive_files.zip ... where ... is replaced by a list of all the files that find found. Run it with echo between -exec and zip to see what it will do:
$ find . -name 'archive' -type d
411/archive
412/archive
488/archive
512/archive
$ find . -name 'archive' -type d -exec echo zip -r all_archive_files.zip {} +
zip -r all_archive_files.zip 411/archive 412/archive 488/archive 512/archive
Related
I am using a directory structure with various folders. There are new files created daily in some of them.
I have created some programs to clean up the directories, but I would like to use a shell script to make it more efficient.
Therefore I would like to store an "archiving.properties" file in every folder that needs to be cleaned up. The properties file should contain the following variables
file_pattern="*.xml"
days_to_keep=2
Now my clean up routine should:
find all properties files
delete all files that match the file name pattern (file_pattern) and that are older then the defined number of days (days_to_keep) in the directory where the properties file was found.
So my question is how can I do this in the most efficient way?
find . -type f -name "archiving.properties" -print
find . -type f -name "<file_pattern>" -mtime +<days_to_keep> -delete
currently I was trying the following in a single folder. It prints out the command correctly, but it is not executed.
#!/bin/bash
. archiving.properties
find . -type f -name "*.xml" -mtime +1 -exec rm -rf {} \;
echo " find . -type f -name \"${file_pattern}\" -mtime +${days_to_keep} -exec rm -rf {} \;"
Result is: find . -type f -name "*.xml" -mtime +1 -exec rm -rf {} \;
Thanks for your help in advance.
I got a final result
echo "start deleting files in " $(pwd) " ... "
#filename of the properties
properties="clean_up.properties"
#find all properties files
for prop in $(find . -type f -name $properties);do
#init variables
file_pattern="*._html"
days_to_keep=14
#load the variables from the properties file
. "$prop"
#define the folder of the properties file
folder=${prop%?$properties}
#remove all files matching the parameters in the folder where the properties were found
echo ">>> find $folder -type f -name \"${file_pattern}\" -mtime +${days_to_keep} -exec rm -f {} \;"
find $folder -type f -name "${file_pattern}" -mtime +${days_to_keep} -exec rm -f {} \;
done
echo "... done"
Directory A having two sub directories B and C. Both B and C having same text file like "abc.txt". From directory A itself how to delete content abc.txt in both directories
If there could be more than two subdirectories in A, but you
want to restrict you to B and C, you can use
rm A/{B,C}/abc.txt
to delete both files.
To empty their content, use
: > A/{B,C}/abc.txt
Delete the actual files:
find A/ -name "abc.txt" -delete
Delete the "content" of the files:
find A/ -name "abc.txt" -exec truncate -s 0 {} \;
The more general way is to use find:
find . -type f -name "file" -exec rm -f {} \;
The explanation of the command is:
-name "file" : file name.
-exec rm -f {} \; : delete the files that match.
-type f : specify the type of file, directory are excluded.
Use Kleene star :
rm A/*/abc.txt
find A/ -name "abc.txt" -type f -exec rm -rf{}\;
Let's say I am in the directory /home/videos and want to iterate recursively through all of the directories underneath it. If the directory name contains "images" I want to delete the directory and all of its contents. Also, can this be done for files? Let's say in each directory go through every file and check if its name ends with ".mp3" and delete it?
Thanks
find . -name "*images*" -type d -exec rm -r {} \;
find . -name "*.mp3" -type f -exec rm -rf {} \;
-exec rm -rf {} \; : Delete all files matched by file pattern.
-type f : Only match files and do not include directory names.
-type d : matches only directory names
Here is a nice tutorial on this. http://www.cyberciti.biz/faq/linux-unix-how-to-find-and-remove-files/
So you can do something like
find /home/videos -type d -name "*images*" -exec rm -rf {} \;
and
find /home/videos -type f -name "*.mp3" -exec rm -rf {} \;
I have a directory with unknown number of subdirectories and unknown level of sub*directories within them. How do I copy all the file swith the same suffix to a new directory?
E.g. from this directory:
> some-dir
>> foo-subdir
>>> bar-sudsubdir
>>>> file-adx.txt
>> foobar-subdir
>>> file-kiv.txt
Move all the *.txt files to:
> new-dir
>> file-adx.txt
>> file-kiv.txt
One option is to use find:
find some-dir -type f -name "*.txt" -exec cp \{\} new-dir \;
find some-dir -type f -name "*.txt" would find *.txt files in the directory some-dir. The -exec option builds a command line (e.g. cp file new.txt) for every matching file denoted by {}.
Use find with xargs as shown below:
find some-dir -type f -name "*.txt" -print0 | xargs -0 cp --target-directory=new-dir
For a large number of files, this xargs version is more efficient than using find some-dir -type f -name "*.txt" -exec cp {} new-dir \; because xargs will pass multiple files at a time to cp, instead of calling cp once per file. So there will be fewer fork/exec calls with the xargs version.
I use Emacs and it sometimes makes backup for edited files. After a few days, I would have a lot of backup files whose name ends with a tilde.
Is there a way to find these files and delete them at once?
I tried this:
find "*" -type f -iname *~
But it doesn't work. I want the command to work recursively – something like ls -alR.
You need to escape from the shell. And you need to specify search path, not *
find . -type f -name '*~'
To delete the files:
find . -type f -name '*~' -exec rm -f '{}' \;
You can do something like that :
find . -type f -name '*~' -delete
If you want to delete also #*# file :
find . -type f -name '*~' -o -name '#*#' -delete
You can print all deleted files with "-print":
find . -type f -name '*~' -delete -print
Another way is by using grep.
lnydex99uhc:javastuff user$ ls
Permutation.java VigenereCipher.java VigenereCipher.java~
lnydex99uhc:javastuff user $ find . | grep .~$
./VigenereCipher.java~
You can also pass any command you want like this :
lnydex99uhc:javastuff zatef$ rm $(find . | grep .~$)