find all files in dir and import 5 lines from each txt file

November 27, 2012 at 08:59:43
Specs: Windows 7

Hi guys,

I need to search a directory for all the files in it, and for each file in it assign variables to each line
of text. These files will be being created and deleted pretty fast as people pull the information
stored in each .txt file in the directory.
Im basically trying to make a queue. So when you check people into the queue you store all their necessary information in a text file. which is 5 lines. then when you want to view the queue, it takes all the information from each text file in a shared folder between all the computers, and displays it as a queue, sorted by the time each person was checked it.
Then when you pull the person from the queue it stores the information locally on just your computer and deletes it from the shared folder.
Is this possible with batch?

Would you like to see my code so far?


See More: find all files in dir and import 5 lines from each txt file

Report •


#1
November 27, 2012 at 12:39:35

"Would you like to see my code so far?"
Yes, that is always helpful, to see what direction you are going, what approach you are taking and how far you have gotten with it.

I'm guessing you mean something like this:
file1
line1
line2
..line5
and you want to view it something like this:
file1 (or user id?) :: line1 :: ine2 ::line3...::line5
id2::line1::line2::line3
id3...
id4...
in other words, make a table, or list, out of all the files' contents? But if that is the case, why not just store the values in linear form instead of list form (lines)?


Report •

#2
November 27, 2012 at 12:49:40

Here is my program so far. Ive been programming for a while now, but I am just
starting off in batch, this is only my second program. So it might seem a little
newbish.
_______________________________________________

@echo off

:MAIN_MENU
CLS

SET M=0

ECHO --- MAIN MENU ---
ECHO.
ECHO (1) VIEW QUEUE
ECHO (2) CHECK IN
ECHO (3) COMPLETE SERVICE
ECHO (X) EXIT
ECHO.
SET /P M=:

IF %M% EQU X ( EXIT )
IF %M% LSS 4 (
IF %M% GTR 0 (
IF %M% EQU 1 ( GOTO VIEW_QUEUE )
IF %M% EQU 2 ( GOTO CHECK_IN )
IF %M% EQU 3 ( GOTO COMPLETE_SERVICE )
) ELSE ( GOTO MAIN_MENU )
) ELSE ( GOTO MAIN_MENU )

:CHECK_IN
CLS

ECHO --- CHECK IN ---
ECHO.
SET /P MEMBERNUMBER=MEMBER NUMBER:
SET /P NAME=MEMBER NAME:
SET /P SERVICE=SERVICE (MS/TA/SL):
SET /P COMMENT=COMMENT:
FOR /F %%A IN ('TIME/T') DO SET NOW=%%A
SET TIMEIN=%NOW%

:CORRECT1
CLS
ECHO MEMBER NUMBER: %MEMBERNUMBER%
ECHO MEMBER NAME: %NAME%
ECHO TIME IN: %TIMEIN%
ECHO SERVICE: %SERVICE%
ECHO COMMENT: %COMMENT%
ECHO.
ECHO IS THIS CORRECT?
SET /P C=(Y/N)

IF %C% EQU Y (
:: SAVE MEMBER INFO TO FILE ON G HERE ::
ECHO %MEMBERNUMBER% > Q\%MEMBERNUMBER%.TXT
ECHO %NAME% >> Q\%MEMBERNUMBER%.TXT
ECHO %TIMEIN% >> Q\%MEMBERNUMBER%.TXT
ECHO %SERVICE% >> Q\%MEMBERNUMBER%.TXT
ECHO %COMMENT% >> Q\%MEMBERNUMBER%.TXT

ECHO !! MEMBER CHECKED IN !!
PAUSE
GOTO MAIN_MENU
)
IF %C% EQU N (
GOTO CHANGE
) ELSE ( GOTO CORRECT1 )

:CHANGE
CLS
ECHO MEMBER NUMBER: %MEMBERNUMBER%
ECHO MEMBER NAME: %NAME%
ECHO TIME IN: %TIMEIN%
ECHO SERVICE: %SERVICE%
ECHO COMMENT: %COMMENT%
ECHO.
ECHO CHANGE WHAT? ( NUM, NAME, SERV, COMT, DONE )
SET /P CHANGE=:

IF %CHANGE% EQU NUM (
ECHO.
SET /P MEMBERNUMBER=MEMBER NUMBER:
GOTO CORRECT1
)
IF %CHANGE% EQU NAME (
ECHO.
SET /P NAME=MEMBER NAME:
GOTO CORRECT1
)
IF %CHANGE% EQU TIME (
ECHO.
SET /P TIMEIN=TIME IN:
GOTO CORRECT1
)
IF %CHANGE% EQU COMT (
ECHO.
SET /P COMMENT=COMMENT:
GOTO CORRECT1
)
IF %CHANGE% EQU DONE (
GOTO CORRECT1
)
GOTO CHANGE


:: This part does not work as you probly could see ::
:: But its my start ::
:: The files will be kept in a directory called 'Q' in the ::
:: same dir as the .bat file, this will later be moved ::
:: but for now this will suffice ::
:VIEW_QUEUE
FOR /F "tokens=*" %%A IN ('DIR /B Q\') DO (
pause
SET /P MNUM1= <%%A
SET /P MNAM1= <%%A
SET /P MTIM1= <%%A
SET /P MSER1= <%%A
SET /P MCOM1= <%%A
) %%A
ECHO %MNUM1%
ECHO %MNAM1%
ECHO %MTIM1%
ECHO %MSER1%
ECHO %MCOM1%
pause
:COMPLETE_SERVICE


Report •

#3
November 27, 2012 at 13:42:58

oops! crossed in the mail, you kind-of answered my questions.
Here's some snippets to work with, depending on what you need to do with this information (this all just ref. "view queue"):

::snippet1: values only displayed, not accessible as variables
for /f "tokens=*" %%a in ('dir /b /o:d') do (
for /f "tokens=*" %%b in (%%a) do echo %%b
)
::==== end snip1
::snippet2: same as #1, but contents displayed on one line, not using delayedexpansion
for /f "tokens=*" %%a in ('dir /b /o:d') do (
for /f "tokens=*" %%b in (%%a) do (
set z=%%b
call :frmt
)
call :output
)
goto :eof
:frmt
set z=%z% :
::set each colunm into 20-space field
set z=%z:~0,20%
set out=%out%%z%
goto :eof
:output
echo %out%
set out=
::==end snip2
:: snip3: assign to variables using delayedexpansion
@echo off
setlocal enabledelayedexpansion
for /f "tokens=*" %%a in ('dir /b /o:d') do (
::first, load the variables with files' content: x1 to x5
for /f "tokens=*" %%b in (%%a) do (
set /a i+=1
set x!i!=%%b
)
::contents loaded, now they are accesible for whatever use
call :output
)
goto :eof
:output
for /L %%L in (1,1,%i%) do echo !x%%L!
set i=0
::end snip3

Report •

Related Solutions

#4
November 27, 2012 at 16:27:35

Wow!... I am... confused.
I will try and implement that in my program.
Do the !'s around the i make it a variable that changes each for loop?

so that the useable variables with my information can be now used in my program
like: echo x1 x2 x3
and it would say something like: 670654 JEFF MS

Also would it be easier if I stored the data in the txt file with commas between
each variable instead of having them each on a new line?
The only problem may be that when inputting the name it will be put in as
first name then a space then a last name: JOHN LENNON
Should i create another variable for the last name?

Sorry if im am a newb.


Report •

#5
November 27, 2012 at 16:31:06

Also what do the /o:d in ('dir /b /o:d') mean?
I've seen in before but what exactly does "tokens=*" actually do?
What does setlocal enabledelayedexpansion actually do?
and what does /L mean in a for loop?

Report •

#6
November 27, 2012 at 20:44:56

"Do the !'s around the i make it a variable that changes each for loop?
so that the useable variables with my information can be now used in my program
like: echo x1 x2 x3
and it would say something like: 670654 JEFF MS"
spot-on!
"Also would it be easier if I stored the data in the txt file with commas between
each variable instead of having them each on a new line?"
Well, reconsidering, I probably went wrong on that idea. You could, but you need to select a delimiter that won't be used in text, which can be difficult. As you pointed out, a comma might be used. You could try more obscure delimiters, but crlf is probably your best bet. A "one-line-per-file" format needs to be formatted in order to work, and that limits total of all fields to 80 bytes before you get wrapping (which confuses the output somewhat). This all depends on the sizes of your fields. The formatting could be suited to each field using another set of vars (f/e: name limit 10, comment limit 30, id limit 5)
"Should i create another variable for the last name?"
As always, that depends ;-) on how you are using the data, and how specific or "formal" you want your system to be.
It's not so much "batch" considerations involved. That's just the "gears and springs". What you need to design is the overall, well, design. "Comment" can be anything, but how long, and what allowable char.s?, "Service" is strict and easily validated, timestamp should be automatic, but what format do you want? (ie readable vs more accurate: 8:04 PM vs 20:04:53.28). Then the user-id, which should be validated in some way, and normally would be tied in to a username file which would eliminate the user having to enter (or mis-enter) his name each time.
You picked a fairly ambitious project for your early batch experience!
As for the specific commands, "USE THE QUESTION-MARK, LUKE!"
at command prompt:
dir /?
for /?
set /?
if /?
etc. etc. Almost all commands have the help feature, so use it!
If you don't use "tokens=*" (or, "delims=") then the variable will only collect up to the first space or tab in the data, and all else will be either discarded or assigned to subsequent var.s.
Here is a rewrite I did (slow night), with comments, that tries to illustrate some points, lets you experiment, and will give you material for further investigation amd questions:
::====== begin script
@echo off
setlocal enabledelayedexpansion
SET QUE=.
:: set field sized for each item
set field1=5
set field2=20
set field3=13
set field4=4
set field5=20

:MAIN_MENU
CLS

SET M=0

ECHO --- MAIN MENU ---
ECHO.
ECHO (1) VIEW QUEUE
ECHO (2) CHECK IN
ECHO (3) COMPLETE SERVICE
ECHO (X) EXIT
ECHO.
SET /P M=:

:: this shortens up the code some
for %%a in (1 2 3 x) do if /i %M% equ %%a goto :%M%
goto :Main_menu
:: note: case is ignored for labels, :X same as :x, at least on xp
:x
EXIT /B

:2
:CHECK_IN
CLS
ECHO --- CHECK IN ---
ECHO.
::clear junk: i learned the hard way, set/P RETAINS content if user
:: hits [ENTER]. It does not become null, so always clear var. before set/p
set membernumber=
set name=
set service=
set comment=

SET /P MEMBERNUMBER=MEMBER NUMBER:
SET /P NAME=MEMBER NAME:
SET /P SERVICE=SERVICE (MS/TA/SL):
SET /P COMMENT=COMMENT:
CALL :TSET

:CORRECT1
:: made this a sub (whenever redundant code content, usually good to make as sub)
CALL :SHOW
ECHO IS THIS CORRECT?
set c=
SET /P C=(Y/N)

:: IF /I will ignore case, so user can type Y or y
IF /I %C% EQU Y (
::================ WRITE DATA ==============
CALL :TSET
REM:: SAVE MEMBER INFO TO FILE ON G HERE ::
REM and this is a good way to do multiple writes (saves re-opening the file
REM as well as code-space re-iterating the filename)
(ECHO.%MEMBERNUMBER%
ECHO.%NAME%
REM override any user-input. They should not have ctrl of timestamp.
REM although we could easily verify it with the file's timestamp.
ECHO %TIMEIN%
ECHO.%SERVICE%
ECHO.%COMMENT%)> %QUE%\%MEMBERNUMBER%.TXT

REM advise to avoid "!" due to enabledelayedexpansion option
ECHO *** MEMBER CHECKED IN ***
:: and this looks "neater"
PAUSE > nul
GOTO MAIN_MENU
)

:CHANGE
CALL :SHOW
SET CHANGE=
SET /P CHANGE=WHAT? ( NUM, NAME, SERV, COMT, [ENTER]=DONE )
IF NOT DEFINED CHANGE GOTO :CORRECT1
ECHO.

:: quotes always a good idea around var.s in IF due to " " (space) possibility.
IF /I "%CHANGE%" EQU "NUM" SET /P MEMBERNUMBER=MEMBER NUMBER:
IF /I "%CHANGE%" EQU "NAME" SET /P NAME=MEMBER NAME:
:: just a suggestion: dis-allow timestamp modification, since users can abuse it...
:: not to mention formatting/parsing/validation nightmares
:: I would have it set automatically at "GO"-time (file-write-event)
::IF /i "%CHANGE%" EQU "TIME" SET /P TIMEIN=TIME IN:
IF /I "%CHANGE%" EQU "COMT" SET /P COMMENT=COMMENT:
IF /I "%CHANGE%" EQU "SERV" SET /P SERV=SERVICE:
CALL :SHOW
SET C=
SET /P C=OK? (Y,else..):
IF /i "%C%" EQU "Y" GOTO :CORRECT1
GOTO :CHANGE

:SHOW
CLS
CALL :TSET
ECHO MEMBER NUMBER: %MEMBERNUMBER%
ECHO MEMBER NAME: %NAME%
ECHO TIME IN: %TIMEIN%
ECHO SERVICE: %SERVICE%
ECHO COMMENT: %COMMENT%
ECHO.
GOTO :EOF
:TSET
REM ::you need "tokens=*" or "delims=" to get all data past the space
FOR /F "TOKENS=*" %%T IN ('TIME /T') DO SET TIMEIN=%%T
GOTO :EOF
:COMPLETE_SERVICE
echo service %service%
goto :eof

:1
:VIEW_QUEUE
for /f "tokens=*" %%a in ('dir /b /o:d *.TXT') do (
set c=0
for /f "tokens=*" %%b in (%%a) do (
set z=%%b
call :frmt
)
call :output
)
:: wait for viewing
set /p null=...
goto :main_menu

:fRmt
set /a c+=1
set z=%z% :
::set each colunm into n-space field, only works with delayedexpansion
set temp=!field%c%!
set z=!z:~0,%temp%!
set out=%out%%z%
goto :eof
:output
echo.%out%
set out=
.


Report •


Ask Question