I'm not quite sure how to do it purely in the terminal without it getting too difficult to read, but I think you could get the result you are looking for, or at least get started, with something along these lines:
Edit: updated with info from the comment. Also swapped secondary and primary since those were backwards.
Edit2: realized that while the secondary name no longer relied on placement, the principle name relied on secondary's placement.
#!/bin/bash
input_directory="/path/to/your/data"
output_directory="/path/to/your/output"
cd "$input_directory"
for file in *; do
if [ ! -f "$file" ]; then
continue;
fi
# place your secondary names inside "(mpc|flf|dtd)" seperated by '|'
secondary=$(echo "$file" | grep -o -E "(mpc|flf|dtd)");
princple=$(echo "$file" | grep -o -E "([0-9]+_S_[0-9]+)");
# skip over and alert that a secondary match was not found for a file
if [ "$secondary" == "" ]; then
echo "No secondary match found!! Skipping $file";
continue;
fi
destination="${output_directory}/$secondary/$princple"
# create the directories if they don't exist
if [ ! -d "$destination" ]; then
mkdir -p "$destination";
fi
# uncomment to move the files to the new directories if the test output
# from echo is correct
#mv "$file" "$destination"
# test to print result of moving the files
from=$(readlink -f "$file")
echo "$from -> $destination/$file"
done
grep -o -E "(mpc|flf|dtd)"
searches the filename for one of the secondary name keywords, e.g. (mpc, dtd or flf), and saves that word to the secondary variable.
grep -o -E "([0-9]+_S_[0-9]+)
Same idea, by looks for the xxx_S_xxx pattern.
It can be run as: bash script.sh
The input_directory
and output_directory
variable will need to be filled in with the correct paths. Also, the fields "(mpc|flf|dtd)" in the grep statement can be filled in with other secondaries.