How to delete all files in a directory except one subdirectory? - unix

I have a directory that contains multiple files and directories and i wanted to delete all the content and exclude one subdirectory; what i did was:
rm -rf * --exclude='directorytokeep'
it worked halfway throu the rm command but once it reached the directory i wanna keep it didn't go after the other files and directories.
thank you

Please test first with
find . -maxdepth 1 ! -name directorytokeep -exec echo rm -rf {} \;
before removing the echo in the command.

Related

Unix Command to delete siblings and parent directory of a given file

I have a directory structure like this
/home
/dir-1
some-file.php
/dir-2
sibling.php
target-file.php
/dir-3
/dir-4
other-sibling.php
sibling.php
target-file.php
/dir-5
target-file.php
I need to target all directories containing the file "target-file.php" and remove those directories with its contents. In my structure, the final result wanted is:
/home
/dir-1
some-file.php
/dir-3
I am trying:
rm -rf /home/*/target-file.php
But it is only removing that file (target-file.php) and not the siblings or the parent directory.
Please help
Use this:
#!/bin/bash
find . -type f -name target-file.php -print0 | while IFS= read -r -d '' line
do
echo "$line"
/bin/rm -fr "$(dirname "$line")"
done
Using find with while like this ensure it will work with all filenames (see https://mywiki.wooledge.org/BashFAQ/001).
You can run find . -type f -name target-file.php -print to see the list of files.
dirname removes the filename so you are left with only the directory names.
/bin/rm -fr deletes the directories.
you can comment the echo line, this was just to show you the files / directories being processed.

Find and replace files from one directory to another WordPress

A site I now manage I found has been corrupted. I would like to keep the content in place, but copy all of the php, txt, and css files from a temporary WordPress installation and move them to the corresponding location using a script.
I don't know how to make a bash or shell script that does something like this:
#!/usr/bash
type = [*\.php|*\.css|*\.ini|*\.txt]
find /temporary/WordPress/ -type f -name '$type' {} + > file-paths-in-temporary-wordpress ;
egrep -o '[a-zA-Z]\.[php|css|ini|txt]' file-paths-in-temporary-wordpress > file-names-of-temporary-WordPress-Installation
find /old/installation/WordPress -type f -name '$type' {} + > file-paths-to-use-as-reference
while read $type in file-names-of-temporary-WordPress-Installation ; do
// locating file-names-of-temporary-WordPress-Installation in old WordPress site, copy files from file-paths-in-temporary-wordpress to the matching locations in the old WordPress installation //
I am confused about how to get this to work. Obviously, this is sorely incomplete.
My desired outcome is to have all of the php, ini, css, and txt files from the fresh WordPress installation copied to the corresponding location at the old WordPress site.
I can use:
find /temporary/WordPress -type f -name '*.php' -exec cp -fvr {} /old/WordPress/Installation/ + ;
find /temporary/WordPress -type f -name '*.css' -exec cp -fvr {} /old/WordPress/Installation/ + ;
..etc.
Any thoughts?
Please help. Thank you!
Why can't you just search each directory and copy if there is a match?
cp /temorary/WordPress/*.php /new/directory/
cp /temporary/WordPress/*.css /new/directory/
...
You can copy everything first and remove things you do not need:
cp -r /temporary/WordPress /old/WordPress/
find /old/WordPress/ -type f -regex ".*\.\(php\|css\|ini\|txt\)" -exec rm {} \;
This might leave empty directories and is fixing things that went wrong (copying files you do not want).
So the right approach is only copying files you need. First go to /temporary/WordPress so you do not need to cut off that dir:
cd /temporary/WordPress
find . -type f -regex ".*\.\(php\|css\|ini\|txt\)" | while read file; do
dir="/old/WordPress/${file%/*}"
mkdir -p "${dir}" 2>/dev/null
cp "${file}" "/old/WordPress/${file}"
done
(Sorry, not tested)

Unix Recursively move all files but keeping the structure

I have a folder named "in" that contains several folders "a" "b" "c" and I want to move all files to thhe folder "proc" and compress them. The tricky part is the files in "in/a" have to be moved to "proc/a", "in/b" have to be moved to "proc/b" and so on
I managed to find all files and zip them whit this command
find . -type f ! \( -name "*gz" -o -name "*tmp" -o -name "*xftp" \) -exec gzip -n '{}' \;
But I'm not finding a generic command to move the files that works whiteout me telling the name of the folders. Can anyone give me a hand?
Well I ended up finding out I had a couple more problems for example the target folder not existing so I ended up using this code
find . -type f ! \( -name "*gz" -o -name "*tmp" -o -name "*xftp" \) -exec gzip -n '{}' \;
find . -name "*.gz" | cpio -p -dumv $1
if [ "$?" = "0" ]; then
find . -name "*.gz" -exec rm -rf {} \;
else
echo "cpio Failed!" 1>&2
exit 1
fi
the 1st line finds all files to be processed and zips them.
the second line finds all files and copies to the target dir, in my case it was $1 (argument 1), creating as many folders as necessary to ensure the same structure.
The third line checks the status of the last command if it worked it finds and removes all gz files from the source folder whiteout deleting any folder. If it didn't deletes nothing so I can analyse what happened (maybe run out of space)
I bet there's a faster way of doing this whiteout having to use so much disk space but since that was not a problem for me it looks acceptable.

Unix 'find' without descending into matched directories

I was trying to remove all git files from a repository with this:
find . -name ".git*" -exec rm -rf {} \;
However, rm warns that files could not be deleted (because their parent directory has already been deleted).
Is there a way to get find to stop recursing when it finds a matching directory?
E.g. find...
/.gitmodules
/.git/stuff
/.git/.gitfile
... produces
/.gitmodules
/.git
Use -depth:
find . -depth -name ".git*" -exec rm -rf {} \;
This would allow you to process the files or subdirectories first before their parent directories.

How to delete only directories and leave files untouched

I have hundreds of directories and files in one directory.
What is the best way deleting only directories (no matter if the directories have anything in it or not, just delete them all)
Currently I use ls -1 -d */, and record them in a file, and do sed, and then run it. It rather long way. I'm looking for better way deleting only directories
To delete all directories and subdirectories and leave only files in the working directory, I have found this concise command works for me:
rm -r */
It makes use of bash wildcard */ where star followed by slash will match only directories and subdirectories.
find . -maxdepth 1 -mindepth 1 -type d
then
find . -maxdepth 1 -mindepth 1 -type d -exec rm -rf '{}' \;
To add an explanation:
find starts in the current directory due to . and stays within the current directory only with -maxdepth and -mindepth both set to 1. -type d tells find to only match on things that are directories.
find also has an -exec flag that can pass its results to another function, in this case rm. the '{}' \; is the way these results are passed. See this answer for a more complete explanation of what {} and \; do
First, run:
find /path -d -type d
to make sure the output looks sane, then:
find /path -d -type d -exec rm -rf '{}' \;
-type d looks only for directories, then -d makes sure to put child directories before the parent.
Simple way :-
rm -rf `ls -d */`
find command only (it support file deletion)\
find /path -depth -type d -delete
-type d looks only for directories, then -depth makes sure to put child directories before the parent. -delete removing filtered files/folders
In one line:
rm -R `ls -1 -d */`
(backquotes)

Resources