Doon_Bogan
Doon_Bogan

Reputation: 381

Identify a directory and move content with find in bash

I want to move all the files of some specific directories to another one single directory called shp_all. The specific directories in question are all those that contain, among others, files with "shp" in their names. the directory looks like:

 -data
 --shp_all
 --d1
 --d2
   ...
 --dN

I managed to dinf a way to identify all the directories, among the d1,...,dN that have files with name "shp":

 find . -name '*shp*' 

However, I don't know how to correctly use exec or execdir to take all the files in the same directory as the output and move them to shp_all

Here is what tried and did not work:

find . -name '*shp*'   -execdir mv '{}/*' shp_all ';' 

Upvotes: 1

Views: 2334

Answers (2)

Rick M
Rick M

Reputation: 1012

I believe one way to do this is the following (keeping in mind the recommendation above from Dave above to move the target directory out of the find path) :

mv $(find . -name "*shp*" -printf "%h\n" | uniq)/* ../shp_all/

Note, that will also move any subdirectories as well. If you really only want files, you can add another level to only find -type f:

mv $(find $(find . -name "*shp*" -printf "%h\n" | uniq) -type f) ../shp_all/

Upvotes: 2

Dave Rix
Dave Rix

Reputation: 1679

You have a small problem here, in that your target path ./shp_all/ is within the path you are searching. This will cause you trouble as files could be moved into the folder before the find gets round to searching the folder.
I would recommend moving that out for the duration of the file selection / move.
The following snippet should be run from within the ./data folder you describe above.

mv ./shp_all ..
find . -name "*shp*" -exec mv {} ../shp_all/ \;

The \; at the end of the find is important to close the -exec otherwise the command will fail to execute.

Hope that helps.
Dave

Upvotes: 1

Related Questions