Move only directories and not files in Unix OS - unix

I had a directory with many files and sub-directories. To move only the sub-directories, I just learned you can use:
ls -d BASEDIR/*/ | xargs -n1 -I% mv % TARGETDIR/

I use the following:
$ mv ./*/ DirToMoveTo
For example:
Say I wanted to move all directories with "Old" in the name to a folder called "Old_Dirs" on /data.
The command would look like this:
mv ./*Old*/ /data/

Why not use find?
find . -maxdepth 1 -type d -exec mv '{}' /tmp \;
-maxdepth 1 makes sure find won't go deeper than current directory
-type d tells find to only find directories
-exec execute a command with the result of the find referenced by {}
In my opinion a cleaner solution and it also works better then using xargs when you have files with white space or tabs in them.

With a file structure like this:
/dir2move2
/dir
/subdir1
/subdir2
index.js
To move only the sub directories and not the files you could just do:
mv ./dir/*/ ./dir2move2

Possible solution:
find BASEDIR/ -maxdepth 1 -mindepth 1 -type d -exec mv '{}' TARGETDIR \;

you can simply use the same command for moving a file but put a slash after the name of the subdirectory
sudo mv */ path/to/destination
sudo mv subdir/ path/to/subdirectory

Related

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: find files in every subdirectory named upd

I have directory tree structure which looks like this
/app/bad/upd /app/pass/upd /app/bad/upd /app/warn/upd
I want to build a find command which can list all the files in every sub-directory named upd.
Currently I list it individually
find /app/bad/upd -type f -name "*${FILE_NAME}*"
This might be what you look for:
find /app -type d -name upd -exec ls -l {} +
or perhaps:
find /tmp/* -type d -name upd -exec sh -c "ls -l {}/*${FILE_NAME}* 2>/dev/null" sh {} \;
If the upd directory is always in the 2nd directory down, you could simply do:
ls /app/*/upd

Copy only files from one directory to another

I'd like to copy a content of directory 1 to directory 2.
However, I'd like to only copy files (and not directories) from my directory 1. How can I do that ?
cp dir1/* dir2/*
then I still have the directories issue.
you can also use this in dir1
find . -type f -exec cp{} dir2/ \;
You may try this one
cp dir1/*.* dir2/*
try this one
find dir1 -type f -exec cp {} dir2/ \;
The currently approved solution will work, however if sub-directories exist, this will also copy the files from the subfolders as well, but instead of putting the copied files in sub folders, it will copy them to dir1.
/dir1/dir1a/test.txt will end up as dir1/test.txt
-maxdepth can be used to only copy files in dir1:
find dir1 -maxdepth 1 -type f -exec cp {} dir2/ \;

How can I append an extension to files that don't already have one?

I have a cron that appends .txt to each file in a directory.
find /path/to/directory -type f -exec mv '{}' '{}'.txt \;
Unfortunately it keeps appending .txt even if it already has it!
My directory looks like this now...
file1.txt.txt.txt.txt.txt.txt.txt.txt.txt
file2.txt.txt.txt.txt.txt.txt.txt.txt.txt
What do you recommend?
You will have to modify your find command to exclude files with extensions.
find /path/to/files ! -name "*.*" -type f -exec mv '{}' '{}'.txt \;
However, this would also mean it would ignore files like:
i.am.a.file.with.no.extension
So if you have files like the above then it's better to use regex option to index the . at $.

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