Linux move files from dir to dir by name mask - linux

I am trying to move all files with names starts with SML from directory to another.
Tried with
find /var/.../Images/ -name SML\* mv /var/.../Images/Small but doesnt work

try find /var/.../Images/ -name SML\* -exec mv {} /var/.../Images/Small/ \;

I guess you want something like this:
dir=/path/to/your/Images
mkdir -p "$dir/Small"
find "$dir" -name "SML*" -not -wholename "$dir/Small/*" -exec mv {} "$dir/Small/" \;
Since the directory you move the files to is a subdirectory of the one you seach in, you need to exclude the files already moved there. So I added -not -wholename "$dir/Small/*"
To execute a command for each found file, you need -exec .... The alternative would be to pipe your find results to a while read loop.
When using -exec, the found name can be referenced by {}.
See man find for a lot more information.

Related

How to rename files in different directories with the same name using find

I have files named test.txt in different directories like this
./222/test.txt
./111/test.txt
I want to rename all test.txt to info.txt
I've tried using this
find . -type f -iname 'test.txt' -exec mv {} {}info \;
I get test.txtinfo
Your idea is right, but you need to use -execdir instead of just -exec to simplify this.
find . -type f -iname 'test.txt' -execdir mv {} info.txt ';'
This works like -exec with the difference that the given shell command is executed with the directory of the found pathname as its current working directory and that {} will contain the basename of the found pathname without its path. Also note that the option is a non-standard one (non POSIX compliant).

Recursive find and copy to other directory

I need to find all files in a directory and it's subdirectories, but I need to keep directory structure. For example there is a file
/media/subdir1/subdir2/file.jpg
and I want to copy it to
/new-media/subdir1/subdir2/file.jpg
and the same to all files inside /media/ directory. And by the way, directories inside /new-media/ must be created if not exist.
if I use
find /media/ -name '*.jpg' -exec cp /new-media/ ????? {} \;
how can I get all subdirectories inside /media/?
The above will get you everything in /media, but to get exactly what you want you probably want to use something like:
Method 1: Copy only what you need recursively, per your requirements:
mkdir ../media2; find . -name "*.jpg" -exec cp -r --parents {} ../media2 \;
I ran this from inside the directory you want to search recursively. It does a couple things:
1 - create the new destination directory
mkdir ../media2
2 - then finds all files ending with ".jpg" recursively.
find . -name "*.jpg"
3 - uses -exec to pass the copy command to each file returned to find as a match, and subs that in as the first argument (which with the syntax of cp, is going to be your source file):
-exec cp -r --parents {} ../media2 \;
the "--parents" flag retains existing directory structure and recursively creates subsequent parent directories. Super useful right?
Method 2: there might be a better way to do this with xargs, but the above ended up being the most simple method imho. That said, if you want to think outside the box, you could simply copy the entire directory over recursively, then remove anything NOT ending with ".jpg" with something like:
cp -r media media2; find ./media '!'-name "*.jpg" -type f | xargs rm
I think this is what you want:
cp -r /media /new-media
-R, -r, --recursive
copy directories recursively
Hope this helps.

How to search (using find command) for directories and copy all the files and directory itself to another directory in linux?

How to search (using find command) for directories and copy all the files and directory itself to another directory in linux?
Here is what I have so far:
find -type d -name "*.ABC" -exec {} /Desktop/NewFile \;
I get this as output:
find: './GAE/.ABC: PERMISSION DENIED
Please Help, Thanks!
Your error here above has nothing to do with file read permission. You're trying to execute the directories you find! Avoid running commands as root or sudo unless: (1) you really need it and (2) you really know what you're doing. Quite often people asking for root or sudo privileges are exactly the ones should not have it.
That said... there are several ways to copy a directory tree under *nix. This is just one possible approach:
$ find <start> -type d -name \*.ABC -exec cp -av {} <target> \;
Where:
<start> is a directory name. It's used to tell find where to start its search (for example /usr/local or $HOME)
<target> is another directory name to define the final destination of your copied directories
UPDATE
In case you want to search for multiple paths...
$ find <start> -type d \( -name \*.ABC -o -name \*.DEF \) -exec cp -av {} <target> \;
This should work:
find ./source_dir -name \*.png -print0 | xargs -0 cp -t path/to/destination
For more info, you can look up here.

Bash - Find several specific folders in a directory and its sbdirectories and rename these specific folders

I just started to study Bash. I want to do a script to find some specific folders in a directory and its subdirectories and if it exist, rename it into the same folder where we have found it. The same specific folder can be in some subdirectories.
I use this:
file=`find . -name a`
if [ -d $file ]
then
rename 's/a/b/' $file
fi
But don't work. Is there anyway to do this process?
Thanks.
Finally, i solved the problem with this:
find . -name "a" -type d -execdir rename 's/a/b/' {} \; &>/dev/null
You can do this with oneliner:
find . -name "a" -type d -execdir rename 's/a/b/' {} \;
The parameter to name might be regex.
With -type d it will find all directories.
-execdir changes to a matching item's directory and then executes the rename command, passing the filename of the item at hand as an argument ({}).

Linux: how to look for files with a certain extension in hierarchy and execute command whenever one is found?

I have a directory hierarchy, whose names do not follow a pattern. E.g.
parent
bcgegec
hfiwehfiuwe
huiwwuifegeufg
whegwgefyfeg
hfeohfeiofe
chidchuehugfe
dedewdewf
tegtgetg
gtgetgtg
and so on.
Inside some of such directories there is a file with "gr" extension. I need to find each of such files, cd to its dir and execute "gnuplot" command having the .gr file as argument. I tried the following to nest two find commands, but the {} of the inner one does not work as I need. The outer find should iterate for every directory, and the inner find should look for the presence of the .gr file.
find $parentDir -type d -exec sh -c '(cd {} && find . -maxdepth 1 -name *.gr -exec /usr/bin/gnuplot {} \;)' \;
Perhaps this is what you are looking for:
find . -type f -name "*.gr" -execdir /usr/bin/gnuplot {} \;
Read through man find for other useful information.

Resources