1.

Solve : regrouping . . . need help with finding specific string(s) . . .?

Answer»

within a text file, then using those strings to rename the file.
Initially, the code would need to loop through all files in a specific directory, where the file names start with I*.

Here is an example of the  text file contents:
 --------------------------------------------------------------------------------------------------
                                              SFC - 011
                                  Transmission Confirmation Message
 For: 90111 Qd                                       Processed: Wed 09-Nov-11 04:04 PM
 --------------------------------------------------------------------------------------------------
 === Sales Order Confirmation Message ===
     Customer: 0057687 QD-GLENWOOD
     **** Delivery Date Exception. Promised Date greater than Required Date. ****
     Required Date: Thu 10-Nov-11                Promised Date: Fri 11-Nov-11
     New Sales Order: 1343944 | OW Order: 417
                --------------------------------------------------------------------

This is an example of the renamed file format that I need:
confirm.057687.000417.110512.083950.cnf
I can get the date/time part, but I need to get the "057687" and "000417" data from inside the file. (Customer:  0057687 on the third line and OW Order: 417 on the sixth line, thought I could use "Customer:" and "OW Order:" strings to find the data to the right of them?)
I've been trying to do this in pieces, but I think I'm making it harder than it needs to be.  At least I'm hoping that's the case.   

Any help would be GREATLY appreciated.Customer:  0057687 on the third line and OW Order: 417 on the sixth line........but I think I'm making it harder than it needs to be

That could be - does Customer: 0057687 not appear on the seventh line and OW Order not appear on the tenth?

so sorry, my mistake on that.  it was only for reference purposes in my post.
Okay, please test this lazy method.  If the file format you provided is correct then the script might extract the Customer and Order numbers for inclusion in the renaming of the file.

Code: [Select]echo off
cls
setlocal enabledelayedexpansion

set zeros=00000
for /f "tokens=*" %%A in ('dir /b /a-d I*.*') do (

more +6 %%A > %temp%\iidiocy
set toks=2
CALL :loop
set Customer=!output!

more +9 %%A > %temp%\iidiocy
set toks=8
call :loop
set Order=!zeros!!output!
set order=!Order:~-6!

echo Customer=!customer!   Order=!order!
)
exit /b

:loop
set /p input=<%temp%\iidiocy
for /f "tokens=%toks%" %%1 in ("!input!") do (
    set output=%%1
)

I in no way present this as being better than T.C.'s solution, I just enjoyed puzzling it out so I thought I might as well post it

Code: [Select]echo off
setlocal enabledelayedexpansion

REM Set file search folder to the same folder as the batch location (testing purposes)
set folder=%~dp0

REM for each file in search folder starting with I
REM you might want to play around with the file mask
for /f "delims=" %%A in ( ' dir /b "%folder%\I*" ' ) do (

REM Search each line in each file for the data we need
for /f "delims=" %%B in ( ' type "%%~dpnxA" ' ) do (

REM use quotes in this way to neutralize some "poison characters" such as | < > etc
set "string=%%B"
REM also replace pipe character ("|") with dot to neutralize it
set "string=!string:|=.!"

REM isolate line with string "Customer:" & get it into variable
echo.!string! | findstr "Customer:">nul && set CustomerLine=!string!

REM isolate line with string "OW Order:" & get it into variable
echo.!string! | findstr "OW Order:">nul && set OWOrderLine=!string!
)

REM get 2nd space delimited token in line with "Customer:"
for /f "tokens=1-2 delims= " %%C in ("!CustomerLine!") do set CustomerNo=%%D

REM Truncate from left to 6 digits
set CustomerNo=!CustomerNo:~-6!

REM get 8th space delimited token in line with "OW Order:"
for /f "tokens=1-8 delims= " %%E in ("!OWOrderLine!") do set OWOrderNo=%%L

REM Add arbitrary number of leading zeros then
REM Truncate from left to 6 digits
set OwOrderNo=00000000!OwOrderNo!
set OwOrderNo=!OwOrderNo:~-6!

REM Generate new filename
REM You said you can get the part I represent as QQQQQQ.RRRRRR
set newfilename=confirm.!CustomerNo!.!OwOrderNo!.QQQQQQ.RRRRRR.cnf

REM Remove "echo" when you are happy it works
echo Ren "%%~dpnxA" "!newfilename!"

)I am sure the provided solutions work fine, but it seems like the problem you are trying to SOLVE is beginning to look like something that could be done more effectively in a real programming language. Quote from: Linux711 on November 12, 2011, 07:29:04 PM

I am sure the provided solutions work fine, but it seems like the problem you are trying to solve is beginning to look like something that could be done more effectively in a real programming language.

Your post is really off-topic for this thread, so I will keep my answer short. People using a computer at work often are not able to install anything extra at all. They have to work with what is actually on the computer that their employer has provided for them, and they have to work within the RESTRICTIONS that their employer's IT department lays down. So no downloads. No fancy programming languages. The supplied Microsoft scripting tools such as Powershell, Visual Basic Script and the NT family command environment (which is not "DOS" as many people think) are all that they can use. And they can do a lot, particularly in a fairly simple text processing scenario like this one, which is what they were designed for. So any considerations of elegance of code etc are misplaced in such a situation. If you look at the original post you will see many clues that the person is working is a commercial corporate environment. (i.e. he's got a "job".) In any case, the code supplied (partly by me admittedly) does the job, so the problem is, in essence, solved. (Pending the OP's return, if that ever happens).
 



Good Morning!
Just got to work and saw these awesome responses!  Thank you sooo much!
Salmon Trout is correct.  I am at work, and usually, the only time we have to use batch files is when we have to rename a translated file to a specific format for our customers that are going to be picking up the file, via ftp.  Unfortunately, our translation software does not allow us to specify the file name upon translation, so we have to manipulate the file name after translation.  Our translation software has a job scheduler that will call a batch file, so that's what calls the batch file after translation.  It's rather a pain, but it is what it is.

I am going to try both of these wonderful pieces of code and I'll post back after I test them here.  Hopefully, I won't have any more questions!

Again, thanks so much!Ok, I was overly optimistic that I might not have any questions . . .
I started with the more simple looking code and I STILL have questions.  Believe me, I KNOW these are embarrassingly simplistic questions, but I'm not familiar with Batch syntax and have just started using it.  BTW . . . if anyone knows of a link to something that would show and explain what all the different characters and commands mean, that would be awesome.  Anyway . . . for this code . . .
T.C.,
Could you possibly add some rem to explain each command and maybe what some of the characters do?
Like what does it mean when you have an "!" before and after a variable?
Was it implied that I was supposed to set a value to %temp%  ?
and was I also supposed to set a value to "iidiocy"  ?
Again, I apologize for the simplistic questions.

echo off
cls
setlocal enabledelayedexpansion

set zeros=00000
for /f "tokens=*" %%A in ('dir /b /a-d I*.*') do (

more +6 %%A > %temp%\iidiocy
set toks=2
call :loop
set Customer=!output!

more +9 %%A > %temp%\iidiocy
set toks=8
call :loop
set Order=!zeros!!output!
set order=!Order:~-6!

echo Customer=!customer!   Order=!order!
)
exit /b

:loop
set /p input=<%temp%\iidiocy
for /f "tokens=%toks%" %%1 in ("!input!") do (
    set output=%%1
)

I've done some commenting on the script but somewhere along the line the script has been compromised.   Please don't run this version

For a fairly comprehensive list of Commands and their syntaxes please go here.. But you don't show your OS so it might not be spot-on specific.

Salmon Trout posted a spiel on environment Variable expansion, perhaps he will post a link to it.

Hope this helps.

Code: [Select]echo off    & REM Turn the echo command to Off so that command lines are
                   not displayed during execution

cls          & REM Clear the display screen

setlocal enabledelayedexpansion
REM                Set the environment to Local i.e. any Set value applied
REM                is valid only within the script and lost when an Endlocal
REM                command is encountered or the script runs to completion or
REM                crashes.   Environment variables are expanded when the
REM                script commences, if the environment variable is to be
REM                expanded during some processing, especially within parenthesis,
REM                then delayed expansion must be invoked.  The environment
REM                variable must be
REM                enclosed in !..! when this is so.

set zeros=00000    & REM  Set the environment variable Zeros

REM  Standard For loop, for info on FOR at the Command Prompt enter For /?
REM  More COPIES the file(s) listed in the Dir listing to a temporary file
REM  iidiocy in the %temp% directory skipping the lines shown by +6 and +9.
REM  To see where your temporary directory is located at the Command Prompt
REM  enter SET T  You should not need to change this in the script, it
REM  should already be set.
REM  The temporary filename need not be changed but you can so do if you wish.

for /f "tokens=*" %%A in ('dir /b /a-d I*.*') do (
                   
more +6 %%A > %temp%\iidiocy
set toks=2
call :loop
set Customer=!output!

more +9 %%A > %temp%\iidiocy
set toks=8
call :loop
set Order=!zeros!!output!
set order=!Order:~-6!

echo Customer=!customer!   Order=!order!
)
exit /b

:loop
REM  set the first line in %temp%\iidiocy as Input.
set /p input=<%temp%\iidiocy

REM Another standard For loop which parses the first line in the file and
REM extracts the customer number on the first call and the OW order number
REM on the second call.
for /f "tokens=%toks%" %%1 in ("!input!") do (
    set output=%%1
)


 T.C.
Thank you so much, this helped tremendously.
It assigns 'output' perfectly, but I've been trying all morning to get it so that I can actually use the variables 'Customer' and 'Orders' to rename the file to:  confirm.!Customer!.!Order!.!Dattim!.cnf  rem do I use the ! around the variables here?

Here's the code that is working to get the specific data for the variables:
echo on rem the only way I know how to debug and watch what gets processed

cls

setlocal enabledelayedexpansion
Set d_qdbconf=\\sourdough\crossdata\ftp\qdoba\test\out\conf_temp  rem the name of the file in here is:  I799126_tlrt_20111114_164903.1
Set tloc_qdbconf=\\sourdough\crossdata\ftp\qdoba\test\out\temp


for /f "tokens=*" %%A in (' dir /b "%d_qdbconf%\I*" ') do (
more +7 %d_qdbconf%\%%A > %tloc_qdbconf%\iidiocy
set toks=2
call :loop
set Customer=!output!

more +9 %d_qdbconf%\%%A > %tloc_qdbconf%\iidiocy
set toks=8
call :loop
set order=!output!
set Order=!order:~-6!


for /F "tokens=2,3,4 delims=/ " %%i in ('date/t') do set dat=%%k%%i%%j
for /F "tokens=5-8 delims=:. " %%i in ('echo.^| time ^| find "current" ') do set tim=%%i%%j%%k
set Dat=!dat:~-6!


)
exit /b

:loop
set /p input=<%tloc_qdbconf%\iidiocy
for /f "tokens=%toks%" %%1 in ("!input!") do (
set output=%%1 
pause[loop]
)

:finish Quote from: jpilch on November 15, 2011, 01:21:17 PM
It assigns 'output' perfectly, but I've been trying all morning to get it so that I can actually use the variables 'Customer' and 'Orders' to rename the file to:  confirm.!Customer!.!Order!.!Dattim!.cnf  rem do I use the ! around the variables here?
...
for /F "tokens=2,3,4 delims=/ " %%i in ('date/t') do set dat=%%k%%i%%j
for /F "tokens=5-8 delims=:. " %%i in ('echo.^| time ^| find "current" ') do set tim=%%i%%j%%k
set Dat=!dat:~-6!


)
exit /b

Before the end parenthesis, try adding this:

Code: [Select]set newname=confirm.!Customer!.!Order!.!Dat!!tim!.cnf
echo ren %%A !newname!
Be sure the echo command shows you what you want to see, then remove the echo and watch it roll. (you may want to add a pause after the echo so you can verify what you are looking at and Ctrl+C to change the code back. Quote from: Original post by jpilch
I can get the date/time part, but I need to get the "057687" and "000417"

Raven has possibly answered your queries but hey, you wanted 000417 not 417.  Are you changing the spec for the script without advising?   Chaos could ensue if you are working from a different spec from us mere mortals. Quote from: T.C. on November 15, 2011, 01:58:18 PM
Raven has possibly answered your queries but hey, you wanted 000417 not 417.  Are you changing the spec for the script without advising?   Chaos could ensue if you are working from a different spec from us mere mortals.

He clearly showed he wanted 000417 in the very first post, and this has been addressed in the answers. Did you read them?


Sorry if I confused anyone, but I don't think I changed anything??

This is getting sooo close!

FYI . . . I had to add some code to 'trim' the 'Customer' and 'Order' variables.  I don't know the code well enough to know why they had trailing spaces, but they did.  So, I looked up how to 'right trim' them and now it looks good . . . I think. 

This is the code I'm running, and I can see the 'move' command and it looks correct now, but it's not doing the 'move'.  Am I missing something?
I tried the 'ren' command, too and it didn't work either.

echo on

cls

setlocal enabledelayedexpansion
Set d_qdbconf=\\sourdough\crossdata\ftp\qdoba\test\out\conf_temp
Set tloc_qdbconf=\\sourdough\crossdata\ftp\qdoba\test\out\temp


for /f "tokens=*" %%A in (' dir /b "%d_qdbconf%\I*" ') do (
more +7 %d_qdbconf%\%%A > %tloc_qdbconf%\iidiocy
set toks=2
call :loop
set customer=!output!
echo."!customer!"
for /l %%a in (1,1,15) do if "!customer:~-1!"==" " set customer=!customer:~0,-1!
echo."!customer!"

set Customer=!customer:~-6!
echo."!Customer!"
pause[trimcustomer]

more +9 %d_qdbconf%\%%A > %tloc_qdbconf%\iidiocy
set toks=8
call :loop
set order=!output!
echo."!order!"
for /l %%a in (1,1,15) do if "!order:~-1!"==" " set order=!order:~0,-1!
echo."!order!"

set Order=!order:~-6!
echo."!Order!"
pause[trimorder]


for /F "tokens=2,3,4 delims=/ " %%i in ('date/t') do set dat=%%k%%i%%j
for /F "tokens=5-8 delims=:. " %%i in ('echo.^| time ^| find "current" ') do set tim=%%i%%j%%k
set Dat=!dat:~-6!

set newname=confirm.!Customer!.!Order!.!Dat!.!tim!.cnf
echo move %d_qdbconf%\%%A %tloc_qdbconf%\!newname!

pause )
exit /b

:loop
set /p input=<%tloc_qdbconf%\iidiocy
for /f "tokens=%toks%" %%1 in ("!input!") do (
set output=%%1 
pause[loop]
)


Discussion

No Comment Found