0

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?

Anh Pham
  • 2,108
  • 9
  • 18
  • 29
dacasine
  • 3
  • 1

2 Answers2

0

Okay, I will use "subfolder" as my subfolder name.

First, creating subfolder within all the dirs

for dir in $(find -type d | grep "/");do mkdir $dir/subfolder; done

I each of one of those, I created a file. I order to move all files within the dirs to the subfolder, I will do something like:

for dir in $(find -type d | grep -vE 'subfolder' | grep '/');do for file in $(find $dir -type f);do mv $file $dir/subfolder;done  ;done

You might want to experiment with --exec in find, but just creating a nested loop was the fastest solution for me.

Let me break it down for you. Here, I try to find all the directories in my path, excluding the subfolder directory and the current one. I could've used -maxdepth 0 with find but since I only had these dirs, it wasnt necessary

for dir in $(find -type d | grep -vE 'subfolder' | grep '/')

Now, in each of those dirs, we try to find all the files (in your case, the zip files and what now).

do for file in $(find $dir -type f)

Now, we just move the found files into the directories from the first loop with the name of the subfolder appended.

do mv $file $dir/subfolder;done  ;done

Keep in mind that since the first loop is closed at the very end, it will do the move operation for 1 directory at a time, and for all files in only that directory. Nested loops can be a bit trickier to understand, especially when someone else does them their own way, I know :(

py9
  • 598
  • 5
  • 15
  • Hi py9, thank you very much for your answer. Seems very logic to me. That said, I tried the command but macOS bash is finding an illegal option -- t. I double checked, replaced -type with -t — still, bash is not accepting. Do you have any idea why ? – dacasine Aug 09 '17 at 08:09
  • Hey, unfortunately I am not working on a MacOS so I am not able to test this out, but searching SO it appears MacOS version of find requires path to be included. In that case, `find -type f` wont work, instead, you should include the path, which would be * basically.. Worth giving a try. More info here: https://stackoverflow.com/questions/17548854/difference-between-mac-find-and-linux-find – py9 Aug 09 '17 at 08:16
  • Thank you. Tried with *, but it blocked due to space errors. – dacasine Aug 09 '17 at 10:13
0

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.

Renaud Pacalet
  • 25,260
  • 3
  • 34
  • 51
  • Thank you very much. Worked like a charm. BTW I am unfortunately the boss. I did not notice the problem at the start of my business 7 years ago... and I will not do the same mistake twice. Have a nice day – dacasine Aug 09 '17 at 10:12
  • @dacasine OK, fine, as you are the boss, may I suggest that instead of `Word & Excel` you chose `WordAndExcel`? No space, no `&` (another special character with a special meaning on the CLI). I swear, you'll thank this decision one day or another. – Renaud Pacalet Aug 09 '17 at 10:27
  • You are right. I'll change it for sure. We decided it to be user-friendly, but we forget that, sometimes, CLI is your best friend to handle massive lists of files. – dacasine Aug 10 '17 at 11:47