Al_Mt
Al_Mt

Reputation: 167

how to create subfolders and move files

I have a folder called p/ and into p/ I have several subfolders, like this:

$[~/p] ls
a/ b/ c/

a/ b/ and c/ also have multiple subfolders each. I'm trying to find a file that match a specific pattern into each folder and subfolder of p/ and move them to a new directory into its corresponding a/, b/ and c/ folder. So, a/ would have a new subfolder called x/ and into x/ will be moved all the matched files found in a/, b/ would have a new subfolder called x/ and into x/ will be moved all the matched files found in b/ and so on.

I have tried:

pth=path/to/p

for dir in ${pth}/*; do 
    mkdir -- "$dir/x";
    find . -name '*match*' -exec mv -t ./x '{}' +;
done

However it's not working, it makes the x/ subfolder into a/, b/ and c/ but it's not moving anything.

I got:

mv: failed to access to './x': No such file or directory

What I'm doing wrong?? Could you help me please?

Edit: This is an example of the structure of the folders:

 p/
 -a/
   --t/
     --q/
       --p/
         -- files-to-match
   --f/
     --qd/
       --pe/
         -- files-to-match
   --d/
     --qu/
       --ip/
         -- files-to-match

Same for folder b and c and the rest of folders that I have. The name of subfolders are not always the same.

The code that @ikegami provide me is working, but the location of the folder x/ ends at the same level of "files-to-match" but I'd like it to be located at the first level, that is at the same level t/, f/ and d/ (for this example).

So the final structure would be:

 p/
 -a/
   --t/
     --q/
       --p/
         -- 
   --f/
     --qd/
       --pe/
         -- 
   --d/
     --qu/
       --ip/
         -- 
   --x/
     --matched-files

Upvotes: 1

Views: 361

Answers (1)

ikegami
ikegami

Reputation: 385829

You're not using the right directory. Change

find . -name '*match*' -exec mv -t ./x '{}' +;

to

find "$dir" -name '*match*' -exec mv -t "$dir/x" '{}' +;

Also, you need to avoid moving files from x by excluding that path.

# $pth can't start with `-`.
# Prefix with `./` if necessary.
# $dir won't start with `-`.

pth=path/to/p

for dir in "$pth"/*; do 
   mkdir "$dir/x";
   find "$dir" \
      -wholename "$dir/x" -prune \
         -or \
      -name '*match*' -exec mv -t "$dir/x" {} +
done

Test

mkdir -p p/a/t/q/p
touch p/a/t/q/p/abc.json
mkdir -p p/a/f/qd/pe
touch p/a/t/q/p/def.json
mkdir -p p/b/t/q/p
touch p/b/t/q/p/ghi.json

pth=p

find "$dir" -name '*.json'
printf -- '--\n'

for dir in "$pth"/*; do 
   mkdir "$dir/x";
   find "$dir" \
      -wholename "$dir/x" -prune \
         -or \
      -name '*.json' -exec mv -t "$dir/x" {} +
done

find "$dir" -name '*.json'

Output

p/a/t/q/p/def.json
p/a/t/q/p/abc.json
p/b/t/q/p/ghi.json
--
p/a/x/def.json
p/a/x/abc.json
p/b/x/ghi.json

Upvotes: 1

Related Questions