Moving alphanumeric files according to the digit in file name

This is the content of my directory

c_g_se1_gb.ph
c_g_se1_gb.ph_pl_s.t
c_g_se1_gb.ph_pl_tr.t
c_g_se3_gb.ph
c_g_se3_gb.ph_pl_s.t
c_g_se3_gb.ph_pl_tr.t
c_g_se2_gb.ph
c_g_se2_gb.ph_pl_s.t
c_g_se2_gb.ph_pl_tr.t
c_g_se4_gb-1.ph
c_g_se4_gb-1.ph_pl_s.t
c_g_se4_gb-1.ph_pl_tr.t
c_g_se4_gb-2.ph
c_g_se4_gb-2.ph_pl_s.t
c_g_se4_gb-2.ph_pl_tr.t

I want to create new directories and simultaneously move the files in the corresponding directories according to the first digit in the file name which is attached with the c_g_se segment. In this case there will be four directories like New_dir1, New_dir2 .. so on. Here c_g_se1_gb.ph, c_g_se1_gb.ph_pl_s.t and c_g_se1_gb.ph_pl_tr.t will be the content of New_dir1.

Any attempts / ideas / thoughts from your side?

This is what I did for testing but its not creating multiple directories. If it work then I will add may be two more for loops for .ph_pl_s.t and .ph_pl_tr.t files

#!/bin/bash
if [ "$1" == "-h" ]; then
  echo "Usage: `basename $0` [Please Enter the starting_file_digit and ending file digit: run as find_move.sh 1 3175]"
  exit 0
fi
printf "\n"
echo Finding and moving *.ph Files from c_g_se"$1"_gb.ph to c_g_se"$2"_gb.ph
for (( c="$1"; c<="$2"; c++ ))
do  
   find -name '*.ph' -exec sh -c 'mkdir -p New_dir"$c" && cp "$@" New_dir"$c"' _ {} +
   printf "\n"
done

Do you want to mv or to cp the files?
And, unlike what you showed in post#1, the number can be multi-digit?

I want mv for for testing I was using cp. Yes the number can be multi-digit. So I used loop here.

Yes, you need a loop. How about

for FN in *.ph*; do TMP=${FN%_${FN#*_*_*_}}; NDTMP="NewDir${TMP#${TMP%%[0-9]*}}"; echo mkdir -p "$NDTMP"; echo mv "$FN" "$NDTMP"; done

remove the echo es when happy with the result.

1 Like

Unfortunately, its not working

Fortunately, it's working (for me).

EDIT: OK, let's be constructive. WHAT "is not working", and how? Please post data to work upon (execution logs, error messages). For me, this was the output:

mkdir -p NewDir123
mv c_g_se123_gb.ph_pl_s.t NewDir123
mkdir -p NewDir1
mv c_g_se1_gb.ph NewDir1
mkdir -p NewDir1
mv c_g_se1_gb.ph_pl_s.t NewDir1
mkdir -p NewDir721
mv c_g_se721_gb.ph NewDir721

And, echo es removed, did exactly what was requested.

1 Like

Thanks, I am not sure what was the problem as in my pc there was no any directory creating with the code. So here is what I did

for FN in *.ph*; do TMP=${FN%_${FN#*_*_*_}}; NDTMP="NewDir${TMP#${TMP%%[0-9]*}}"; echo mkdir -p "$NDTMP"; echo mv "$FN" "$NDTMP"; done > find_n_move.sh

chmod +x find_n_move.sh 

Added #!/bin/bash to file 

./find_n_move.sh

So its done. Many Thanks. May be you can also let me what was the problem with

find -name '*.ph' -exec sh -c 'mkdir -p New_dir"$c" && cp "$@" New_dir"$c"' _ {} +

Of course no directory was created nor was a file moved - the commands were echo ed to the screen for control purposes. Redirecting to find_n_move.sh and the running that is one option. One other would be to read my post#6 to its entirety and remove the echo es as proposed.

To your second question: What do you expect people to do with the little info you give? May I repeat myself (post#8): WHAT "is not working", and how? Please post data to work upon (execution logs, error messages.
Aside: your construct cp "$@" New_dir"$c"' _ {} seems a bit weird...