Who can finish this script?

Good morning dear friends,

I want to write an UNIX script to do the following task:

We have 6 directories, called (SMS_01, SMS_02 ....... SMS_06), some files are distributed across these directories, but the distribution process is not good, I mean when I check these directories I found the following result:

drwxr-xr-x 3 root system 1495040 Sep 09 08:06 SMS_01
drwxr-xr-x 2 root system 256       Sep 09 15:48 SMS_02
drwxr-xr-x 2 root system 256       Sep 09 15:42 SMS_03
drwxr-xr-x 2 root system 256       Sep 09 15:45 SMS_04
drwxr-xr-x 2 root system 256       Sep 09 15:37 SMS_05
drwxr-xr-x 2 root system 256       Sep 09 15:55 SMS_06
 

All what I want is the distribution process done equally across these 6 directories, so each one receive 100 files for example.

Waiting your ideas.
Many thanks

What is the source of the files? If you control that you could maintain a counter within it and send the next file to printf "SMS_0%d", (file_count % 6) + 1

otherwise you'd have to "post process" by, for example, running find to geta count of files only within the directory structure and then running find and sending the first 1/6th of files to sms_01 etc...

but we're unlikely to finish work you haven't started (or indeed fully specified)

Hello Skrynesaver
Thanks for your suggestions.
I started many times and write some lines but I can't get the idea, I don't know how to distribute the files equally.

Anyway, the files generated from other servers, these files are transferring automatically through ftp to the these directories.

I have an idea but I can't translate it into shell script, the idea is: after receiving the files, suppose directory number 1 received 210 files, and directory number 2 didn't receive any thing, and directory number 3 received 117 files, and directory # 5 received 80 files, and directory # 6 didn't receive.

So, at this point, how can I redistribute the whole files equally, so every directory has the some number of files?!

#!/usr/bin/ksh
TOTAL_NR_OF_FILES=$(find SMS_* -type f | wc -l)
AVG=$(expr $TOTAL_NR_OF_FILES / 6)

SUFFIX=1
MOVED=0
for FILENAME in $(find SMS_* -type f)
do
 if [ $MOVED -eq $AVG ]
 then
   SUFFIX=$(expr $SUFFIX + 1)
   MOVED=0
 fi
 echo mv $FILENAME SMS_0${SUFFIX}/$(basename $FILENAME) 2>/dev/null
 MOVED=$(expr $MOVED + 1)
done

You may remove the red echo after verifying the output.

Note: The script has to be executed from the directory where all the SMS* directories are available.

1 Like

Dear krishmaths,
The script seems good, I will try it now in testbed server then I will tell you the result.
Thank you very much.

A good start, but IMHO not correct. One must consider source directories above average and target directories below average...

Hello my friend,

I created 6 directories (MMU_01, MMU_02 .... MMU_06) and I distributed 24 files between them (not equally) then I applied this script (after changing the name of directories from SMS_* into MMU_*)

But nothing moved between directories, i.e. the empty directories still empty, and the directory which have 11 files still have the same number.

I think there is something missing in the script.

Please check the out put with me as the following:

Here is the 6 directories + the script file:

[P550_APP4][root]/Scripts/test> ls -l
drwxr-xr-x    2 root     system         4096 Sep 10 10:04 MMU_01
drwxr-xr-x    2 root     system          256 Sep 10 09:54 MMU_02
drwxr-xr-x    2 root     system          256 Sep 10 09:56 MMU_03
drwxr-xr-x    2 root     system          256 Sep 10 09:56 MMU_04
drwxr-xr-x    2 root     system          256 Sep 10 10:01 MMU_05
drwxr-xr-x    2 root     system          256 Sep 10 09:54 MMU_06
-rwxr-xr--    1 root     system          331 Sep 10 10:06 test.sh

After applying the script, this result appearing:

[P550_APP4][root]/Scripts/test> ./test.sh
mv MMU_01/dwe.txt MMU_01/dwe.txt
mv MMU_01/dwedwe.txt MMU_01/dwedwe.txt
mv MMU_01/dwesqwsqdwe.txt MMU_01/dwesqwsqdwe.txt
mv MMU_01/dwesqwsqddwedqwe.txt MMU_01/dwesqwsqddwedqwe.txt
mv MMU_01/dwesq45e.txt MMU_02/dwesq45e.txt
mv MMU_01/dwesq45342e.txt MMU_02/dwesq45342e.txt
mv MMU_01/dwesq242e.txt MMU_02/dwesq242e.txt
mv MMU_01/dwesq24e.txt MMU_02/dwesq24e.txt
mv MMU_01/dwe232wqwsq24e.txt MMU_03/dwe232wqwsq24e.txt
mv MMU_01/dwe232w4rqwsq24e.txt MMU_03/dwe232w4rqwsq24e.txt
mv MMU_01/dsqdqw2 MMU_03/dsqdqw2
mv MMU_01/1231 MMU_03/1231
mv MMU_01/97dws MMU_04/97dws
mv MMU_03/rterterte.sh MMU_04/rterterte.sh
mv MMU_03/rtertertewefrwe.sh MMU_04/rtertertewefrwe.sh
mv MMU_03/rterffdstewefrwe.sh MMU_04/rterffdstewefrwe.sh
mv MMU_03/rterfeewe.sh MMU_05/rterfeewe.sh
mv MMU_03/rtesrfeewe.sh MMU_05/rtesrfeewe.sh
mv MMU_03/rtesrf4eewe.sh MMU_05/rtesrf4eewe.sh
mv MMU_04/tyuio.jpg MMU_05/tyuio.jpg
mv MMU_04/tyuiowewew.jpg MMU_06/tyuiowewew.jpg
mv MMU_04/tyuiowewew2dsw.jpg MMU_06/tyuiowewew2dsw.jpg
mv MMU_05/ghgydf.txt MMU_06/ghgydf.txt
mv MMU_05/ghgy.txt MMU_06/ghgy.txt

Then I checked the first directory to make sure, but it still have 11 files!

[P550_APP4][root]/Scripts/test> cd MMU_01
[P550_APP4][root]/Scripts/test/MMU_01> ls -l
total 0
-rw-r--r--    1 root     system            0 Sep 10 10:04 1231
-rw-r--r--    1 root     system            0 Sep 10 10:04 97dws
-rw-r--r--    1 root     system            0 Sep 10 10:03 dsqdqw2
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwe.txt
-rw-r--r--    1 root     system            0 Sep 10 09:55 dwe232w4rqwsq24e.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwe232wqwsq24e.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwedwe.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwesq242e.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwesq24e.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwesq45342e.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwesq45e.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwesqwsqddwedqwe.txt
-rw-r--r--    1 root     system            0 Sep 10 09:54 dwesqwsqdwe.txt

Please help me, I'm sure something is missing, or something need to be corrected.

---------- Post updated at 02:22 AM ---------- Previous update was at 02:20 AM ----------

Yes it is good script, I learned some concepts from Mr. krishmaths.
I appreciate your notes, kindly refer to the previous reply to see the result, and apply your notes into script to fix the problems, because it needs some correction.

Thanks a lot MadeInGermany :slight_smile:

The output you have shown looks good. The mv statement is trying to move 4 files each to the 6 directories.

Now you may remove the "echo" before mv statement and run the script to actually move the files.

I have tested this for number of files not being exact multiple of 6 as well and it worked.

aha, yes I see the result on the monitor and it seems good, but nothing moved.
I understand you now when you said remove echo after verified.

Done.
The result is great.
Thanks a lot Mr. krishmaths

---------- Post updated at 05:25 AM ---------- Previous update was at 02:38 AM ----------

Another point please.
After this distribution process is done, there are some services is down, don't worry about that.
Now I wrote a small script called (jjjjj.sh) to check if the process is up, if no the script will up it.

Note:
rating = the name of the user who own the service.

PRE_VOICE_O_2 = the service name which I look for it.

The long line in the script, don't worry about it, just check the first 2 lines.

 
ps -fu rating |grep -E "PRE_VOICE_O_2" | grep -v grep | awk '{print $2}' | wc -l | read PRE_VOICE
if [ PRE_VOICE -le 1 ]
then
nohup /bossapp1/rating/bin/ratprecdr PRE_VOICE_O_2 1 1 1 0 97 106 1 >>~/log/precdr/prevoice2.out &
fi

Now, when I run it, this error is appearing:
./jjjjj.sh: line 2: [: PRE_VOICE: integer expression expected

Looks like you missed a $ to refer the variable.

if [ $PRE_VOICE -le 1 ]

Thanks dear.
The problem was a tiny note:
Thr word (rating) which is the user name, I must write it in a separate line as the following: user=rating
then in all lines I must write:

 
ps -fu $user |grep -E "PRE_VOICE_O_2" | grep -v grep | awk '{print $2}' | wc -l | read PRE_VOICE

another note, I must write the line: #!/usr/bin/ksh in the beginning

In the future, when the follow up is unrelated to the thread's topic, start a new thread.

Regards,
Alister

1 Like

Yes, right.
Sorry for that Alister

If you don't have any preference which file goes where, you could try

mkdir tmpdir
DIRS=( $(ls -d S*) )
FILES=( $(ls tmpdir/*) )
CNT=$((${#FILES[@]} / ${#DIRS[@]}))
for D in ${DIRS[@]}; do for ((i=0; i<=$CNT; i++)); do echo mv ${FILES[ST++]} $D; done; done
rmdir tmpdir

Many thanks RudiC
I will try it.

Anyway, now I'm using Mr. krishmaths's script.
But it is good to have 2 versions of the same script :slight_smile:

Thanks