Search code examples
bashmacosshellfilemv

Mv files contained in directories to directories/new path


I'm working with macOS Sierra.

I have ~ 1000+ directories with lots of files in it. Word, Excel and Zipped documents in it. Only one sub level. Important : there is spaces in the filenames and in the folder names.

We decided to change the arborescence of the files ; all the files in each directory need to be moved to a subdirectory in it called "Word & Excel" before merging with another directory tree.

I managed to create the Word & Excel directory with this command :

for dir in */; do mkdir -- "$dir/Word & Excel"; done

Basically, I just want to do

for dir in */; do mv $dir/* "./Word & Excel"; done

It is not going to work. I even do not understand if the problem is with the $dir — I need the double quote to avoid the space problem, but the asterisk is not going to work if I work with the double quote... — or with the asterisk.

I tried to get a cleaner version by following a previous answer found on the web to a similar problem, clearing the subfolder of the results (and trying basically to avoid my wildcard problem) :

for dir in */; do mv `ls -A "$dir" | grep -v "Word & Excel"` ./"Word & Excel" | cd ../ ; done

I am completely stuck.

Any idea how to handle this?


Solution

  • This should make it, even on Mac OS X. And yes, find sometimes needs the anchor directory.

    while read dir; do
      mkdir -p "$dir/Word & Excel"
      find "$dir" -maxdepth 1 -type f -exec mv {} "$dir/Word & Excel" \;
    done < <(find . -mindepth 1 -maxdepth 1 -type d)
    

    This loops over the sub-directories of the current directory (one sub-level only), for each of them (dir), creates the dir/Word & Excel sub-sub-directory if it does not already exist, finds all regular files immediately inside dir and moves them in the dir/Word & Excel. And it should work even with crazy directory and file names.

    This being said, if you could convince your boss not to use unusual file or directory names, you life with bash and the Command Line Interface (CLI) would probably be much easier.