Reputation: 167
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
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