# Solved: mail zip files based on foldername



## lgsadmin (Oct 17, 2011)

Hi there,

I have some zip files and I would like to email these to different email addresses.
The zipfiles include xlm files (invoices) and I want to mail these files.

The problem is that I only have a txt document including the emailaddresses. This could be changed to a csv file if needed.

Is there any way I can match a zipfile to an emailaddress. The zipfile name is the customer account number in our backoffice system.
So if I can match the customer account number to an emailaddress this woul be perfect.

Also I have to mail this automatically using blat.exe (command line mailer).

Does anybody have a solution for me ?
Thanks in advance.

// Edwin.


----------



## Squashman (Apr 4, 2003)

If you have a text file with the account numbers and email addresses this isn't a really big deal.

So if this is what your text file looks like with the account numbers and emails

```
12345 [email protected]
45321 [email protected]
23454 [email protected]
```
You can use the following code to get that data into two variables using the following code. For simplicity sake I am just echo'ing the data back out.

```
@echo off
FOR /F "tokens=1,2" %%I IN (account_emails.txt) DO (
	echo account number is: %%I
	echo email address is: %%J
	)
```
So your output looks like this then.

```
E:\batch files\email>email.bat
account number is: 12345
email address is: [email protected]
account number is: 45321
email address is: [email protected]
account number is: 23454
email address is: [email protected]
```


----------



## lgsadmin (Oct 17, 2011)

Squashman,

Yes, this is what I needed.
Although I have one question.
What if there is no folder, because our backoffice software doesn't have any invoices for a specific customer.

In this case, the customer receives an empty mail. Is is possible to add something like "if exist %%I, then send mail".

Now I have the following code:

```
@echo off
FOR /F "tokens=1,2" %%I IN (account_emails.txt) DO (
 echo account number is: %%I.rar
 echo email address is: %%J
blat.exe "email_body.txt" -to %%J -subject "Invoices" -attach xmlfiles\%%I.zip -server 10.18.0.15 -f [EMAIL="[email protected]"][email protected][/EMAIL] -mime
 )
```
Like I said, this works, but it checks account_emails.txt and if it found an entry, the mail is send.
I would like to check first if the %%I.zip exists and then send the mail. If %%I.zip is not found, the mail to that customer should not be send.

Can you please help me out here ?

If the code works, I will put the complete batch script online. (fyi, some words are in Dutch, but most of the people can figure out the code)


----------



## Squashman (Apr 4, 2003)

lgsadmin said:


> Is is possible to add something like "if exist %%I, then send mail".


You nailed it right on the head. Just read the help for the IF command. Type *IF /?* at the a cmd prompt.

```
H:\>if /?
Performs conditional processing in batch programs.

IF [NOT] ERRORLEVEL number command
IF [NOT] string1==string2 command
IF [NOT] EXIST filename command

  NOT               Specifies that Windows XP should carry out
                    the command only if the condition is false.

  ERRORLEVEL number Specifies a true condition if the last program run
                    returned an exit code equal to or greater than the number
                    specified.

  string1==string2  Specifies a true condition if the specified text strings
                    match.

  EXIST filename    Specifies a true condition if the specified filename
                    exists.

  command           Specifies the command to carry out if the condition is
                    met.  Command can be followed by ELSE command which
                    will execute the command after the ELSE keyword if the
                    specified condition is FALSE
```


----------



## lgsadmin (Oct 17, 2011)

Yes, that's what I've tried, but it doesn't seem to work.
This is the code now. Can you see what's wrong ?
It looks like I have an error with the syntax, but I'm not experienced with Dos, FOR, IF, etc.


```
@echo off
FOR /F "tokens=1,2" %%I IN (account_emails.txt) DO (
 echo account number is: %%I.rar
 echo email address is: %%J
IF EXIST %%I.zip
blat.exe "email_body.txt" -to %%J -subject "subject" -attach xmlfiles\%%I.zip -server 10.18.0.15 -f [EMAIL="[email protected]"][email protected][/EMAIL] -mime
 )
```


----------



## Squashman (Apr 4, 2003)

You need to have that all on one line or you need Parenthesis just like you do for the For Loop. The parenthesis tells the batch file that the line is continuing. So you need:
IF EXIST %%I.zip blat.exe ...........
or
IF EXIST %%I.zip (
BLAT.exe ....
)


----------



## lgsadmin (Oct 17, 2011)

You are completely right.
I've changed my lines to use parenthesis and it's working fine now.

I will add all my steps (6 in total) to a new reply on this message.


----------



## Squashman (Apr 4, 2003)

You can in Theory put the entire thing on one line if you don't use the ECHO statements which really aren't needed. But I always like readability which is why I put things on multiple lines.

```
FOR /F "tokens=1,2" %%I IN (account_emails.txt) DO IF EXIST %%I.zip blat.exe "email_body.txt" -to %%J -subject "subject" -attach xmlfiles\%%I.zip -server 10.18.0.15 -f [email protected] -mime
```


----------



## lgsadmin (Oct 17, 2011)

This is my total script to analyse xml files, move them, zip the files en finally mail them.

*step1.bat*

```
@echo off
copy *.xml xmlbackup
```
*step2.bat*

```
REM @echo off
REM Zoek in de huidige directory naar alle xml bestanden
for /f "delims=" %%f in ('dir /b *.xml') do (    
REM Zoek in het xml bestand naar de key <name> dit aanpassen naar het echte veld
FOR /F "tokens=2 delims=><" %%i in ('findstr "<name>" %%f') do (        
REM Maak een directory aan met de naam gevonden in de key hierboven
mkdir %%i 
REM Kopieer het betreffende xml bestand in de juiste folder
move %%f %%i ) 
)exit)
```
*step3.bat*

```
for /D %%I in (*) do move %%I xmlfiles\
```
*step4.bat*

```
cd xmlfiles\
for /D %%I in (*) do "C:\Program Files\WinRAR\winrar" a -afzip -r %%I.zip %%I\*.*
cd ..
```
*step5.bat*

```
@echo off
FOR /F "tokens=1,2" %%I IN (account_emails.txt) DO (
 echo account number is: %%I.zip
 echo email address is: %%J
IF EXIST xmlfiles\%%I.zip (
blat.exe "email_body.txt" -to %%J -subject "LOGUS XML facturen" -attach xmlfiles\%%I.zip -server 10.18.0.15 -f [EMAIL="[email protected]"][email protected][/EMAIL] -mime
)
 )
```
You can see that it opens account_emails.txt.
This is what is in the file:

```
31206 [EMAIL="[email protected]"][email protected][/EMAIL]
41206 [EMAIL="[email protected]"][email protected][/EMAIL]
```
As you can see the first numbers are the value of the XML key from step 2. Then you see the email address from, in my case, my customer. You have to manually edit this file.

*step6.bat*

```
rd xmlfiles /s /q
md xmlfiles
```
From 1 batch file I start every step in each order. (sorry if some words are in Dutch, but based on the steps above you can get an idea of what the code does.

*Total.bat*

```
@echo off
echo ******************************************************************
echo *   1. Maak een backup van de xml bestanden                      *
echo ******************************************************************
call stap1_xmlbackup.bat
@ping 127.0.0.1 -n 5 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
echo ******************************************************************
echo *   2. Verplaats XML facturen naar juiste map                    *
echo ******************************************************************
call stap2_xmlfactuur.bat
@ping 127.0.0.1 -n 5 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
 
echo ******************************************************************
echo *   3. Verplaats folders naar juiste map                         *
echo ******************************************************************
call stap3_foldermove.bat
@ping 127.0.0.1 -n 8 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
 
echo ******************************************************************
echo *   4. Maak een zip bestand van elke map                         *
echo ******************************************************************
call stap4_xmlzip.bat
@ping 127.0.0.1 -n 5 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
 
echo ******************************************************************
echo *   5. Verstuur het zip bestand naar de klant                    *
echo ******************************************************************
call stap5_xmlemail.bat
@ping 127.0.0.1 -n 5 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
 
echo ******************************************************************
echo *   6. Verwijder de inhoud van xmlfiles                          *
echo ******************************************************************
call stap6_folderdelete.bat
@ping 127.0.0.1 -n 5 -w 1000 > nul
@ping 127.0.0.1 -n %1% -w 1000> nul
 
echo ******************************************************************
echo ******************************************************************
echo ******************************************************************
echo **  Voltooid                                             **
echo ******************************************************************
echo ******************************************************************
GOTO END
:END
pause
REM exit
```


----------



## Squashman (Apr 4, 2003)

Why are you using the PING commands to delay the processing of the next step?

Batch files are sequential processing. It will not proceed to the next step until the previous step has completed.


----------



## lgsadmin (Oct 17, 2011)

Why ? well, when I've tested the total.bat file, the move of the files and the zipping of the files went wrong.
When I put a delay in the file, it works perfectly.
Also I tested it by using start /w step1.bat, but it didn't work also.
Maybe it's not needed, but for me it works right now and people can see the messages on the screen.


----------



## Squashman (Apr 4, 2003)

It should work without the PING commands delaying the the execution. That is how batch files work. Sequential processing.

And *START /w* will not work because you need to use *START /wait*.

If all your users who run this batch file are using Windows Vista or Windows 7 then you can replace the PING commands with the TIMEOUT command. This allows you to pause execution of your batch file in number of seconds.


----------



## Squashman (Apr 4, 2003)

lgsadmin said:


> As you can see the first numbers are the value of the XML key from step 2. Then you see the email address from, in my case, my customer. You have to manually edit this file.


What is causing you to manually edit this file?


----------



## lgsadmin (Oct 17, 2011)

I have to edit this file, because in the XML file there is no value with the email address.
This address is only available in the backoffice system itself.

All my users are working on a Terminal Server (Windows 2003) so the timeout function will not work.


----------



## Squashman (Apr 4, 2003)

lgsadmin said:


> I have to edit this file, because in the XML file there is no value with the email address.
> This address is only available in the backoffice system itself.
> 
> All my users are working on a Terminal Server (Windows 2003) so the timeout function will not work.


Even better. I assumed your users were just using Windows Destkops. If you look real hard you will notice that TIMEOUT is also available for Windows 2003 server. Just type *TIMEOUT /?* at the cmd prompt to see the help and syntax.


----------



## lgsadmin (Oct 17, 2011)

I see that the TIMEOUT function is working, but it gives a countdown to 0.
Then I added the > nul at the end of the TIMEOUT command and it does now exactly what I want.
Perfect.

You also had a question about manually editing the txt file and why I did this.
Like I explained in my earlier post, the e-mail address is only available in de backoffice and not in the XML file, or do you have an other option ?
Changing the XML is not possible because it's been generated by the backoffice system.


----------



## Squashman (Apr 4, 2003)

Batch file will not be able to pull from your Back Office system. I was thinking that if your BackOffice system is putting the customer number into the XML file why can't it be programmed to put the email address in the XML file.

In regards to the TIMEOUT command there is another alternative for that as well. If you have the Windows 2003 resource kit installed, it has the SLEEP command. This command shows no output when executed. So if you use *SLEEP 10*, the batch file will just sit there for 10 seconds and you will not see a countdown.


----------



## lgsadmin (Oct 17, 2011)

If it was possible to edit the XLM output I would, but this is not possible 

If I put > nul afer the TIMEOUT command, the countdown isn't visable also.

So all my problems are solved now.

Thank you for your help !!


----------



## lgsadmin (Oct 17, 2011)

Squashman,

I still have one problem and maybe you can help me with this.
I have the following code to examine a XML file:

```
REM @echo off
for /f "delims=" %%f in ('dir /b *.xml') do (    
FOR /F "tokens=2 delims=><" %%i in ('findstr "<gln>" %%f') do (        
mkdir %%i 
move %%f %%i ) 
)exit)
```
The problem is that I have multiple <gln> items in my XML file.
I only want the third <gln> item, because that's the code of my client.
Is it possible to skip the other <gln> items and only look for the third item ?

I hope to hear from you soon.

Edwin.


----------



## Squashman (Apr 4, 2003)

I would need to see an example of your XML file.


----------



## lgsadmin (Oct 17, 2011)

Sure, thats possible.
I will upload it as an attachement.

I'm looking for the third <gln> entry. (<gln>8700000000889</gln>)


----------



## Squashman (Apr 4, 2003)

Set a counter variable and increment it by 1. When the counter equals 3 create your directory and and move your file.


----------



## lgsadmin (Oct 17, 2011)

Okay, but how do I set a variable in my batch script ?
This is the script i use:


```
@echo off
for /f "delims=" %%f in ('dir /b *.xml') do (    
FOR /F "tokens=2 delims=><" %%i in ('findstr "<gln>" %%f') do (        
mkdir %%i 
move %%f %%i ) 
)exit)
```
Somewhere in that code I have to put a variable. Can you help me out please ?


----------



## Squashman (Apr 4, 2003)

I do not often give people the fish. I would rather teach you to fish. I will give you the three lines you need. You put them where they need to go.

```
set _Counter=0
set /a _Counter+=1
IF "!_Counter!"=="3"
```


----------



## lgsadmin (Oct 17, 2011)

Squashman,

Thanks for the variables.
I thought I had it, but now the script doesn't work.

First of all, I begin the script by setting the counter to 0.
Then, when it tries to find <gln> I set the counter to 1 and if it counts <gln> for the third time, the folder should be created.

This is what I have so far.
It works till the If "!_Counter construction. If I remove this line, the script works, but with the line it doesn't. I don't know why, because I'm not into this kind of scripting. For me it's hocus pocus. I can see what is does, but don't know the codes.

```
@echo off
set _Counter=0
for /f "delims=" %%f in ('dir /b *.xml') do (    
FOR /F "tokens=2 delims=><" %%i in ('findstr "<gln>" %%f') do (        
set /a _Counter+=1
If "!_Counter!"=="3"
mkdir %%i 
move %%f %%i ) 
)exit)
```


----------



## Squashman (Apr 4, 2003)

Setting the counter to Zero needs to be in between the two For Loops otherwise when it processes your 2nd XML file it will not process it because the counter will never equal 3 again.

And I am pretty sure I told this too you before, You need to use parenthesis with your IF commands. So you will basically have three sets of parenthesis in your code. One set for each FOR loop and One set for your IF command.


----------



## Squashman (Apr 4, 2003)

Not sure why you have the EXIT command in there. That will basically kill your batch file after it processes the first XML file.


----------



## Squashman (Apr 4, 2003)

For simplicity sake I am just echoing your Loop Variables. I like to indent my batch file and put the closing parenthesis where the initial command started. Makes it easier to see where everything starts and stops.


```
@Echo Off & SetLocal EnableExtensions EnableDelayedExpansion
for /f "delims=" %%f in ('dir /a-d /b *.xml') do (
	set _Counter=0
	FOR /F "tokens=2 delims=><" %%i in ('findstr "gln" %%f') do (
		set /a _Counter+=1
		IF "!_Counter!"=="3" (
			echo %%i 
			echo %%f %%i
		)
	)	 
)
```


----------



## lgsadmin (Oct 17, 2011)

Squashman,

The only thing that is different (I think) is the <gln> key.
I put it into code tags any you put it between "

The parenthesis was something that was wrong in my version like you said before.

Thanks again for all your help.


----------



## Squashman (Apr 4, 2003)

lgsadmin said:


> The only thing that is different (I think) is the <gln> key.
> I put it into code tags any you put it between "


I saw no point in using the Opening and Closing XML tags in the FINDSTR command. Works the same with or without.


----------



## Squashman (Apr 4, 2003)

Actually realized I could shorten this code up a little bit and not even use a counter. It wouldn't really speed it up that much though. Just a different way to skin the cat.


----------

