Board logo

标题: [ZT]纯DOS下读取文件首行为变量,一句话 » [打印本页]

作者: electronixtar     时间: 2006-10-11 04:36    标题: [ZT]纯DOS下读取文件首行为变量,一句话 »

原文见二楼
ECHO EXIT|%COMSPEC%/KPROMPT E100'SET VAR='$_RCX$_8$_NFILE1.BAT$_W$_Q|DEBUG>NUL
[ Last edited by electronixtar on 2006-11-4 at 11:32 PM ]

作者: electronixtar     时间: 2006-10-11 04:45    标题: [ZT]纯DOS下读取文件首行为变量,一句话

lf.8k.com/BAT/FVAR.TXT
:::::::::::::: :::::::::::::::::::::::::::::: Last Modified: 2001-07-29 : Author : Laura Fairhead : :::::::::::::: :::::::::::::::::::::::::::::: How do I get a single line text file into an environment variable? ------------------------------------------------------------------ A common problem encountered in DOS for which the solution is not obvious is how one might read a line of text in a file into a DOS environment variable. For example to get the current directory one might start with; CD>FILE.TXT If only you could do something like; SET VAR=readfile("FILE.TXT") But DOS has no such abilities. Here are presented a number of the known ways to perform this function, throughout the same naming convention is used; FILE.TXT = the single line text file to read VAR = the name of the variable to get the line into Auxillary file solution ~~~~~~~~~~~~~~~~~~~~~~~ This is the standard book solution. (i) At the command prompt enter "COPY CON FILE1.BAT", type the text "SET VAR=" and terminate the line by pressing CTRL+Z first, then ENTER. This creates a file that contains the text "SET VAR=" with no newline on the end. (ii) Use the following code in your batch file; ====================================================================== COPY FILE1.BAT FILE2.BAT TYPE FILE.TXT >>FILE2.BAT CALL FILE2.BAT DEL FILE2.BAT ====================================================================== After this VAR will be set with the contents of FILE.TXT The problem with this method is that it requires an auxillary file that goes together with the main batch program. The above lines work fine if they are run while in the same directory as the auxillary file however will fail if it is not. It is desirable for the auxillary file to be stored together with the batch file in it's directory, then there are 2 possibilites to solve this problem (A) "hard-code" the location of FILE1.BAT. So if the batch file and FILE1.BAT are put into C:\UTILS you would use the following lines ====================================================================== COPY C:\UTILS\FILE1.BAT FILE2.BAT <--- path to FILE1.BAT hardcoded TYPE FILE.TXT >>FILE2.BAT CALL FILE2.BAT DEL FILE2.BAT ====================================================================== Hardcoding PATHs to files is generally considered extremely bad programming practice, but this maybe sufficient in certain contexts (for example if the batch is for floppy). (B) Locate the directory of the batch & FILE1.BAT using code. This is the usual solution for professional software, however to do this using only batch language is extremely awkward and it requires around a dozen or so lines of code. DEBUG script edit solution ~~~~~~~~~~~~~~~~~~~~~~~~~~ The problem with the "AUXILLARY FILE" algorithm could easily be solved by getting the batch file to create FILE1.BAT. There is a problem with this however; ECHO SET VAR=>FILE1.BAT Creates a file with the text "SET VAR=" and a newline appended. There is no way possible to convince the ECHO command not to append the newline, it does this with anything that it outputs. Here is where DEBUG can help out; ====================================================================== ECHO E100"SET VAR=">$ FOR %%_ IN (RCX 8 NFILE1.BAT W Q) DO ECHO %%_>>$ DEBUG <$ >NUL ====================================================================== The first 2 lines of the above create a DEBUG script file "$"; ====================================================================== E100"SET VAR=" RCX 8 NFILE1.BAT W Q ====================================================================== When fed into DEBUG it creates a 8 byte file consisting of the text "SET VAR=" with no newline on the end. So having created FILE1.BAT (in the current directory) the program can go on to use it to complete the algorithm; ====================================================================== ECHO E100"SET VAR=">$ (1) FOR %%_ IN (RCX 8 NFILE1.BAT W Q) DO ECHO %%_>>$ (2) DEBUG <$ >NUL (3) DEL $ (4) TYPE FILE.TXT>>FILE1.BAT (5) CALL FILE1.BAT (6) DEL FILE1.BAT (7) ====================================================================== Many variations on this are possible and common. The creation of the file can actually be done much more compactly; ====================================================================== ECHO EXIT|%COMSPEC%/KPROMPT E100'SET VAR='$_RCX$_8$_NFILE1.BAT$_W$_Q|DEBUG>NUL ====================================================================== This replaces lines 1-4 in the above. The temporary file is now implicit (handled by DOS pipes) so doesn't require deletion. The first two stages in the pipeline produce the following output; ====================================================================== E100'SET VAR=' RCX 8 NFILE1.BAT W QEXIT ====================================================================== The PROMPT command has been utilized in order to output newlines directly here. With COMMAND /K switch the arguement is executed as a shell command and then it continues by executing standard input. There is no need for an additional '$_' after the 'Q' because debug only looks at 'Q' itself and ignores any trailing garbage on the line. SED solution ~~~~~~~~~~~~ SED is an industry standard UNIX utility and a very good, compact, freeware port for DOS exists; ftp://ftp.simtel.net ... SED can solve many tasks standing on its head that plain DOS finds either impossible or _extremely_ awkward. This is one of them; ====================================================================== SED "s/^/SET VAR=/" FILE.TXT >FILE1.BAT CALL FILE1.BAT DEL FILE1.BAT ====================================================================== ASCII CODE ~~~~~~~~~~ ASCII code is machine code that can be represented by printable ASCII characters. Often this is very carefully crafted by hand so that the program does not contain any binary values which are unprintable ASCII codes (less than hex20), shell special characters (<, >, |...) or possibly untransportable 8-bit characters (greater than hex7F). The result is a machine code .COM program which can be created simply using ECHO (program ) >CODE.COM. This is very flexible and transportable code and reduces file access overhead; ===================================================================== ECHO XPYP[*'CC-\1P\QX,=P,APZ5O!PQ2O~5aaI~}Ksx>_.COM ===================================================================== This is an ASCII code program that when run simply ECHO's text but with no newline on the end. So; _ SET VAR=>FILE1.BAT Then creates the desired base FILE1.BAT Of course having created the _.COM echo program it can be used again and again throughout the batch, only being deleted on exit. It is obviously useful for a great deal more than this one particular task. Of course the full atomic operation will be peformed now by the lines; ===================================================================== ECHO XPYP[*'CC-\1P\QX,=P,APZ5O!PQ2O~5aaI~}Ksx>_.COM _.COM SET VAR=>FILE1.BAT TYPE FILE.TXT>>FILE1.BAT CALL FILE1.BAT DEL FILE1.BAT DEL _.COM ===================================================================== Here is a full disassembly of the machine code generated with commenting; ===================================================================== ;on entry to .COM program: ; SP=FFFE, a 0 word is on the stack ; DS=ES=SS=CS ; CS:0->PSP ; ; contrary to some information out there AX is not always 0 ; this is the 4th revision of this code, the 3rd assumed AX=0000 ; ; Since all the segment registers are the same and remain the ; same throughout they are not mentionned any further ;AX=0000 CX=0000 BX=0000 1777:0100 58 X POP AX 1777:0101 50 P PUSH AX 1777:0102 59 Y POP CX 1777:0103 50 P PUSH AX 1777:0104 5B [ POP BX ;[BX]=[0]=BYTE AT PSP OFFSET 0 ;the word at PSP offset 0 is a INT 20 instruction (CD 20) ;before a COM program is entered 0 is pushed to the stack ;this means that a RET instruction will 'JMP 0' execute ;the INT 20 and consequently return to DOS ;however here is used the value 'CD' ;and AH=00-CD =33 1777:0105 2A 27 *' SUB AH,[BX] ;BX=0002 1777:0107 43 C INC BX 1777:0108 43 C INC BX ;AX=01A4 1777:0109 2D 5C 31 -\1 SUB AX,315C ;SP=01A4 1777:010C 50 P PUSH AX 1777:010D 5C \ POP SP ;AX=0000 1777:010E 51 Q PUSH CX 1777:010F 58 X POP AX ;AX=00C3 1777:0110 2C 3D ,= SUB AL,3D ;[01A2]=C3 00 1777:0112 50 P PUSH AX ;AX=0082 1777:0113 2C 41 ,A SUB AL,41 ;DX=0082 1777:0115 50 P PUSH AX 1777:0116 5A Z POP DX ;AX=21CD 1777:0117 35 4F 21 5O! XOR AX,214F ;[01A0]=CD 21 C3 00 1777:011A 50 P PUSH AX ; ; now at: 01A0: CD 21 INT 21 ; 01A2: C3 RET ; 01A3: 00 ; ;stack pointer is just below it at 01A0 (predecrementing). ;This is adjusted deliberately to be as far away from the ;program as possible (for stack space) but still being ;able to reach this _generated_ code with a relative jump. *[1] ; ;and now a 0 word is pushed. This is so that when the 'RET' ;at 01A2 is encountered the program will 'JMP 0' and hence ;INT 20 and return to DOS ;get 0 word ready for next POP (the RET) 1777:011B 51 Q PUSH CX ;CL=00 XOR [0080] = [0080] ; The number of characters in the command line tail (in the PSP) 1777:011C 32 4F 7E 2O~ XOR CL,[BX+007E] ;AX=40xx (21CD XOR 6161=40xx) ; only the value in AH is important 1777:011F 35 61 61 5aa XOR AX,6161 ; this has been preparing for a DOS call; ; ; AH=40 write handle function ; BX=0001 DOS stdout ; CX=#chars chars to write ; DX=0082 start of text to output ; ;DX is set to 0082 instead of 0081 (the actual start of the command line ;tail data in the PSP) because DOS starts writing the command tail ;from/including the character deliminating the command. So if you started ;at 0081 the result of 'ECHOCOMMAND hello' would be the text ' hello' ;just incrementing to 0082 doesn't solve the problem completely. CX needs ;to be decremented so that 1 less character is output. 1777:0122 49 I DEC CX ;Now if CX has decremented to -1 (from 0) we must skip the call. JNG ;will jump if ZF=1 OR SF<>OF. The overflow flag must be clear due to ;the limited range of CX, so that evaluates to ZF=1 OR SF=1. So it ;skips the output call if there are no characters to output as well. 1777:0123 7E 7D ~} JNG 01A2 ;BX=0001 1777:0125 4B K DEC BX ;CF=0 after the XOR AX,6161 by definition and the intermediate instructions ;do not change it so this is simply a 'JMP'. Of course JMP = 0EBh ;which is outside the range of printable ASCII characters (020h to 07Eh) ;that are allowed in the program. 1777:0126 73 78 sx JNC 01A0 --------------------------------------------------------------------- *[1]: Certain instructions that _need_ to be executed can not be represented with the ASCII codes 020h - 07Eh, so the method has to be that those instructions are generated somehow. I had seen other ASCII machine code programs that did this by modifying later parts of themselves so that when they fell through to those stages the instructions were there. There is a serious problem with self modifying code like this on 486 and earlier processors, the prefetch queue is loaded ahead of code execution (on 486 I think it is maybe as much 32 bytes) and any modifications to code that falls in that range will only effect memory--- the preloaded(unmodified) instructions will still execute. On the Pentium they changed the processor logic so that a write in the range of the prefetch queue will cause it to be immediately reloaded from memory. On 486 and earlier you need to have some sort of JMP instruction to cause it to be reloaded first. Try making a program this small with a jump instruction to another part of the program..... ===================================================================== ~~
[ Last edited by electronixtar on 2006-11-4 at 11:31 PM ]

作者: zouzhxi     时间: 2006-10-11 04:47
lf.8k.com/BAT/CK.TXT
CLOCK - time display utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is a little application that keeps an updated display of the current time on the screen. The time is displayed using large characters (either 8x7 or 8x14 character cells per character ) in a choice of two styles- either a normal monochrome font or a colour graphics font. The program automatically selects one of these two styles depending on whether or not it finds ANSI.SYS installed but that behaviour can be overridden by a command line option. There is also an option to select between normal and double size characters for the display. Character generation ~~~~~~~~~~~~~~~~~~~~ The large characters are generated from a built in font which is 8x8 pixels in size. As the characters are generated one by one they are written to a display buffer array in 8 environment variables, one for each line; %L!% row1 %L!!% row2 %L!!!% row3 %L!!!!% row4 %L!!!!!% row5 %L!!!!!!% row6 %L!!!!!!!% row7 %L!!!!!!!!% row8 Naming the variables in this way makes it easier for the batch to use them by using a bang counter variable. The main working routine is a program generated batch file named %TMP0%. This is produced by the code at :DGVE (right down until before :RTIME), the main program simply redirects the output of this routine to the file %TMP0%. The structure of the %TMP0% file is part of a very important set of general structures for batch files that allows many data-base type operations. The first line of the file is simply; %1 Which allows the file to be called with the first parameter as 'GOTO:record_name'. And that record will be retrived. Here, the record is the graphics of a single digit and it is appended directly to the display buffer variables; :C2 SET L!=%L!% 2222 SET L!!=%L!!% 22 22 SET L!!!=%L!!!% 22 SET L!!!!=%L!!!!% 22 SET L!!!!!=%L!!!!!% 22 SET L!!!!!!=%L!!!!!!% 22 SET L!!!!!!!=%L!!!!!!!% 222222 SET L!!!!!!!!=%L!!!!!!!!% GOTO OUT The prefix 'C' is necessary because there have been reported problems with a numeric as the first character of a label name and it can cause various difficulties with batch program also. :DGVE also generates records for all the other digits 0-9 and also a record for the colon character (called C_3A) and the period (called C_2E). The last generated line of the %TMP0% file is a ':OUT' label to allow each record to exit from the file after being called. Because it takes a while to create this file the program does not delete it on exit, and it performs a test on startup to see if the file already exists. The implementation actually 'tags' the first line of the file; %1 % !<id> % The variable ' !<id> ' obviously can't exist (since it can't be SET) so always evaluates to nothing, so the text in-between allows various information to be put into the file without affecting it's operation (although any SPACE characters added must be considered carefully). In this case '<id>' is a special identifier the program uses so that later it can determine if the file was generated by it, and also that it is the type of file it needs (the program actually generates one of 2 files depending on whether the display is ANSI or normal). :DGV is called to generate each character record. The parameters to the call are; CALL %0 . GOTO:DGV labelname mark row1left row1right ..... row8left row8right 'labelname' is simply the name of the label that is going to be the first line of the record. 'mark' is a single character to use to represent each filled square in the display representation. Unfilled squares are always represented as a SPACE character. :DGV does not actually use the 'mark' character if it the display style is ANSI graphics, with ANSI graphics the 'mark' character is always character 0xFE (255 dec), a small block. Then comes the actual graphic data which is in hexadecimal. Each parameter is a 4 pixel chunk, start from the top left of the character and going left to right, top to bottom. This format allows the font to be stored very compactly and also to be generated quickly and easily from data using standard utilities- I didn't have to design the font for this program I just used a quick 'awk' script to convert it from a font file. Getting the current time ~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Full listing TESTED: DOS7 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @ECHO OFF IF !%1==!. %2 %COMSPEC% /E:4096 /C %0 . GOTO:START %1 GOTO OUT :START FOR %%_ IN (0 1) DO SET TMP%%_=%TEMP%.\@%%_.BAT SET COM=%COMSPEC%/E:4096 SET F=%0 ECHO EXIT|%COM%/KPROMPT SET ESC=$E$_:>%TMP1% CALL %TMP1% MEM/C |FIND "ANSI ">NUL SET ANSI=TRUE IF ERRORLEVEL 1 SET ANSI=FALSE :: use ANSI graphics - set to FALSE here to stop :: SET ANSI=FALSE :: vertical enlarge option - change to set default SET VE=FALSE :L4 SHIFT IF !%2==! GOTO K5 IF !%2==!BIG SET VE=TRUE IF !%2==!SMALL SET VE=FALSE IF !%2==!NORMAL SET ANSI=FALSE IF NOT !%2==!/? GOTO L4 ECHO %F% [/?] [NORMAL] [BIG] [SMALL] ECHO batch clock utility ECHO NORMAL specifies not to use ANSI.SYS colour graphics ECHO. which is default if the program detects it is installed ECHO BIG uses double height character font ECHO SMALL uses normal height character font (default) ECHO. GOTO QUIT :K5 SHIFT IF NOT !%3==! GOTO L4 FOR %%_ IN (C0 C1) DO SET %%_= IF %ANSI%==TRUE SET C0=%ESC%[1;31m IF %ANSI%==TRUE SET C1=%ESC%[0m IF NOT EXIST %TMP0% GOTO K3 FIND "%% !@FBBC%ANSI% %%" <%TMP0% >NUL IF NOT ERRORLEVEL 1 GOTO K4 :K3 ECHO PLEASE WAIT... %COM%/C %F% . GOTO:DGVE >%TMP0% :K4 :L1 SET _= ECHO EXIT|%COM%/KPROMPT $T&|%COM%/C %F% . GOTO:RTIME >%TMP1% CALL %TMP1% CALL %F% . GOTO:WRT %_% CHOICE /C%ESC%N /TN,01>NUL IF ERRORLEVEL 2 GOTO L1 :QUIT IF EXIST %TMP1% DEL %TMP1% GOTO OUT :WRT SHIFT SHIFT IF !%8==! %F% . GOTO:WRT1 0 %1 : %2 %3 . %4 %5 %F% . GOTO:WRT1 %1 %2 : %3 %4 . %5 %6 :WRT1 FOR %%_ IN (! !! !!! !!!! !!!!! !!!!!! !!!!!!! !!!!!!!!) DO SET L%%_= :L0 SET _=C%3 IF %3==: SET _=C_3A IF %3==. SET _=C_2E CALL %TMP0% GOTO:%_% SHIFT IF NOT !%3==! GOTO L0 ECHO EXIT|%COM% /K PROMPT SET _=$D$_:>%TMP1% CALL %TMP1% CLS FOR %%_ IN (. .) DO ECHO. IF %VE%==FALSE FOR %%_ IN (. . .) DO ECHO. ECHO. ____________________________________________________________________ ECHO. %_% ECHO.[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] ECHO.[ %C0%%L!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!%%C1% ] ECHO.[ %C0%%L!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!%%C1% ] ECHO.[ %C0%%L!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!%%C1% ] ECHO.[ %C0%%L!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!%%C1% ] ECHO.[ %C0%%L!!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!!%%C1% ] ECHO.[ %C0%%L!!!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!!!%%C1% ] ECHO.[ %C0%%L!!!!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!!!!%%C1% ] ECHO.[____________________________________________________________________] ECHO [ESC] To exit ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IF %ANSI%==TRUE ECHO %ESC%[30m%ESC%[K%ESC%[0m%ESC%[A GOTO OUT :DGVE ECHO %%1 %% !@FBBC%ANSI% %% CALL %F% . GOTO:DGV C_2E . 0 0 0 0 0 0 0 0 0 0 1 8 1 8 0 0 CALL %F% . GOTO:DGV C0 0 3 C 6 6 6 E 7 E 7 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C1 1 1 8 3 8 1 8 1 8 1 8 1 8 7 E 0 0 CALL %F% . GOTO:DGV C2 2 3 C 6 6 0 6 0 C 1 8 3 0 7 E 0 0 CALL %F% . GOTO:DGV C3 3 3 C 6 6 0 6 1 C 0 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C4 4 0 C 1 C 3 C 6 C 7 E 0 C 0 C 0 0 CALL %F% . GOTO:DGV C5 5 7 E 6 0 7 C 0 6 0 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C6 6 1 C 3 0 6 0 7 C 6 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C7 7 7 E 0 6 0 C 1 8 3 0 3 0 3 0 0 0 CALL %F% . GOTO:DGV C8 8 3 C 6 6 6 6 3 C 6 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C9 9 3 C 6 6 6 6 3 E 0 6 0 C 3 8 0 0 CALL %F% . GOTO:DGV C_3A : 0 0 0 0 1 8 1 8 0 0 1 8 1 8 0 0 ECHO :OUT GOTO OUT :DGV SET S= %=% SET M=%4 IF %ANSI%==TRUE SET M=?SET C=! ECHO :%3 :DGL SET _= FOR %%_ IN (CALL SHIFT) DO %%_ %F% . GOTO:DGE %5 FOR %%_ IN (CALL SHIFT) DO %%_ %F% . GOTO:DGE %5 ECHO SET L%C%=%%L%C%%%%_% SET C=%C%! IF NOT %C%==!!!!!!!!! GOTO DGL ECHO GOTO OUT GOTO OUT :DGE IF %3==0 SET _=%_%%S%%S%%S%%S% IF %3==1 SET _=%_%%S%%S%%S%%M% IF %3==2 SET _=%_%%S%%S%%M%%S% IF %3==3 SET _=%_%%S%%S%%M%%M% IF %3==4 SET _=%_%%S%%M%%S%%S% IF %3==5 SET _=%_%%S%%M%%S%%M% IF %3==6 SET _=%_%%S%%M%%M%%S% IF %3==7 SET _=%_%%S%%M%%M%%M% IF %3==8 SET _=%_%%M%%S%%S%%S% IF %3==9 SET _=%_%%M%%S%%S%%M% IF %3==A SET _=%_%%M%%S%%M%%S% IF %3==B SET _=%_%%M%%S%%M%%M% IF %3==C SET _=%_%%M%%M%%S%%S% IF %3==D SET _=%_%%M%%M%%S%%M% IF %3==E SET _=%_%%M%%M%%M%%S% IF %3==F SET _=%_%%M%%M%%M%%M% GOTO OUT :RTIME FOR %%_ IN ( 0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL 1%%_ SET _=%_% %%_ CHOICE /C&&&&&&&&&0123456789>NUL IF ERRORLEVEL 10 GOTO RTIME ECHO SET _=%_% EXIT :OUT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ Last edited by zouzhxi on 2006-10-11 at 04:50 ]

作者: zouzhxi     时间: 2006-10-11 04:53
lf.8k.com/BAT/LC.TXT
@ECHO OFF ::***********RENAME ALL FILES IN CURRENT DIRECTORY TO LOWERCASE************ ::SET THIS TO 'NUL' TO BIN OUTPUT SET U=CON ::SET UP DOSKEY MACROS SET Q=FOR %% SET R= IN ("SET T SET S=") DO %% :GOTO DOSKEY ENTER=SET T=$*$T%%Q%%n%%R%%=%%S%%%%T%%$T%%Q%%e%%R%%=%%S%%%%T%%$T%%Q%%w%%R%%=%%S%%%%T%%$T%%Q%%" "%%R%%=%%S%%%%T%%$T%%Q%%t%%R%%=%%S%%%%T%%$T%%Q%%i%%R%%=%%S%%%%T%%>$ DOSKEY INVALID=%%Q%%m%%R%%=%%S%%%%T%%$T%%Q%%e%%R%%=%%S%%%%T%%$T%%Q%%:%%R%%=%%S%%%%T%%$T%%Q%%" "%%R%%=%%S%%%%T%%$TREN "%%T%%" "%%T%%"$TECHO "%%T%%" to "%%T%%"$G%%U%%>>$ DOSKEY CURRENT=REM ::(REINSTALL DOSKEY IF OUT OF SPACE) FC NUL $|FIND "*">NUL IF NOT ERRORLEVEL 1 FOR %%_ IN ("ECHO OUT OF MACRO SPACE.. REINSTALLING DOSKEY" "DOSKEY /R" "GOTO:GOTO") DO %%_ ::GET FILENAME LIST READY TO PROCESS DIR/L/B>$ ECHO.>>$ TIME<$>$.BAT DEL $ ECHO INVALID>>$.BAT ECHO EXIT>>$.BAT ::NOW $.BAT READY CALL IT CTTY NUL %COMSPEC% /K<$.BAT CTTY CON DEL $.BAT FOR %%_ IN (Q R S T U) DO SET %%_= FOR %%_ IN (ENTER INVALID CURRENT) DO DOSKEY %%_=

作者: electronixtar     时间: 2006-10-11 05:32
……还是不要把和主题无关的帖子发过来的好……

作者: done     时间: 2006-10-11 07:02
这个是dos还是汇编啊

作者: weilong888     时间: 2006-10-11 08:51
这些可不大容易搞清楚啊。

作者: needed     时间: 2006-10-11 22:24
我还是没有看懂,如果是借助外部命令的话,不用这么复杂. 如果只用内部命令,我看不到例子

作者: zouzhxi     时间: 2006-10-11 23:21
我也是在这个地方找的,不懂它的用法... 地址:lf.8k.com/BAT/CK.TXT
CLOCK - time display utility ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is a little application that keeps an updated display of the current time on the screen. The time is displayed using large characters (either 8x7 or 8x14 character cells per character ) in a choice of two styles- either a normal monochrome font or a colour graphics font. The program automatically selects one of these two styles depending on whether or not it finds ANSI.SYS installed but that behaviour can be overridden by a command line option. There is also an option to select between normal and double size characters for the display. Character generation ~~~~~~~~~~~~~~~~~~~~ The large characters are generated from a built in font which is 8x8 pixels in size. As the characters are generated one by one they are written to a display buffer array in 8 environment variables, one for each line; %L!% row1 %L!!% row2 %L!!!% row3 %L!!!!% row4 %L!!!!!% row5 %L!!!!!!% row6 %L!!!!!!!% row7 %L!!!!!!!!% row8 Naming the variables in this way makes it easier for the batch to use them by using a bang counter variable. The main working routine is a program generated batch file named %TMP0%. This is produced by the code at :DGVE (right down until before :RTIME), the main program simply redirects the output of this routine to the file %TMP0%. The structure of the %TMP0% file is part of a very important set of general structures for batch files that allows many data-base type operations. The first line of the file is simply; %1 Which allows the file to be called with the first parameter as 'GOTO:record_name'. And that record will be retrived. Here, the record is the graphics of a single digit and it is appended directly to the display buffer variables; :C2 SET L!=%L!% 2222 SET L!!=%L!!% 22 22 SET L!!!=%L!!!% 22 SET L!!!!=%L!!!!% 22 SET L!!!!!=%L!!!!!% 22 SET L!!!!!!=%L!!!!!!% 22 SET L!!!!!!!=%L!!!!!!!% 222222 SET L!!!!!!!!=%L!!!!!!!!% GOTO OUT The prefix 'C' is necessary because there have been reported problems with a numeric as the first character of a label name and it can cause various difficulties with batch program also. :DGVE also generates records for all the other digits 0-9 and also a record for the colon character (called C_3A) and the period (called C_2E). The last generated line of the %TMP0% file is a ':OUT' label to allow each record to exit from the file after being called. Because it takes a while to create this file the program does not delete it on exit, and it performs a test on startup to see if the file already exists. The implementation actually 'tags' the first line of the file; %1 % !<id> % The variable ' !<id> ' obviously can't exist (since it can't be SET) so always evaluates to nothing, so the text in-between allows various information to be put into the file without affecting it's operation (although any SPACE characters added must be considered carefully). In this case '<id>' is a special identifier the program uses so that later it can determine if the file was generated by it, and also that it is the type of file it needs (the program actually generates one of 2 files depending on whether the display is ANSI or normal). :DGV is called to generate each character record. The parameters to the call are; CALL %0 . GOTO:DGV labelname mark row1left row1right ..... row8left row8right 'labelname' is simply the name of the label that is going to be the first line of the record. 'mark' is a single character to use to represent each filled square in the display representation. Unfilled squares are always represented as a SPACE character. :DGV does not actually use the 'mark' character if it the display style is ANSI graphics, with ANSI graphics the 'mark' character is always character 0xFE (255 dec), a small block. Then comes the actual graphic data which is in hexadecimal. Each parameter is a 4 pixel chunk, start from the top left of the character and going left to right, top to bottom. This format allows the font to be stored very compactly and also to be generated quickly and easily from data using standard utilities- I didn't have to design the font for this program I just used a quick 'awk' script to convert it from a font file. Getting the current time ~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Full listing TESTED: DOS7 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @ECHO OFF IF !%1==!. %2 %COMSPEC% /E:4096 /C %0 . GOTO:START %1 GOTO OUT :START FOR %%_ IN (0 1) DO SET TMP%%_=%TEMP%.\@%%_.BAT SET COM=%COMSPEC%/E:4096 SET F=%0 ECHO EXIT|%COM%/KPROMPT SET ESC=$E$_:>%TMP1% CALL %TMP1% MEM/C |FIND "ANSI ">NUL SET ANSI=TRUE IF ERRORLEVEL 1 SET ANSI=FALSE :: use ANSI graphics - set to FALSE here to stop :: SET ANSI=FALSE :: vertical enlarge option - change to set default SET VE=FALSE :L4 SHIFT IF !%2==! GOTO K5 IF !%2==!BIG SET VE=TRUE IF !%2==!SMALL SET VE=FALSE IF !%2==!NORMAL SET ANSI=FALSE IF NOT !%2==!/? GOTO L4 ECHO %F% [/?] [NORMAL] [BIG] [SMALL] ECHO batch clock utility ECHO NORMAL specifies not to use ANSI.SYS colour graphics ECHO. which is default if the program detects it is installed ECHO BIG uses double height character font ECHO SMALL uses normal height character font (default) ECHO. GOTO QUIT :K5 SHIFT IF NOT !%3==! GOTO L4 FOR %%_ IN (C0 C1) DO SET %%_= IF %ANSI%==TRUE SET C0=%ESC%[1;31m IF %ANSI%==TRUE SET C1=%ESC%[0m IF NOT EXIST %TMP0% GOTO K3 FIND "%% !@FBBC%ANSI% %%" <%TMP0% >NUL IF NOT ERRORLEVEL 1 GOTO K4 :K3 ECHO PLEASE WAIT... %COM%/C %F% . GOTO:DGVE >%TMP0% :K4 :L1 SET _= ECHO EXIT|%COM%/KPROMPT $T&|%COM%/C %F% . GOTO:RTIME >%TMP1% CALL %TMP1% CALL %F% . GOTO:WRT %_% CHOICE /C%ESC%N /TN,01>NUL IF ERRORLEVEL 2 GOTO L1 :QUIT IF EXIST %TMP1% DEL %TMP1% GOTO OUT :WRT SHIFT SHIFT IF !%8==! %F% . GOTO:WRT1 0 %1 : %2 %3 . %4 %5 %F% . GOTO:WRT1 %1 %2 : %3 %4 . %5 %6 :WRT1 FOR %%_ IN (! !! !!! !!!! !!!!! !!!!!! !!!!!!! !!!!!!!!) DO SET L%%_= :L0 SET _=C%3 IF %3==: SET _=C_3A IF %3==. SET _=C_2E CALL %TMP0% GOTO:%_% SHIFT IF NOT !%3==! GOTO L0 ECHO EXIT|%COM% /K PROMPT SET _=$D$_:>%TMP1% CALL %TMP1% CLS FOR %%_ IN (. .) DO ECHO. IF %VE%==FALSE FOR %%_ IN (. . .) DO ECHO. ECHO. ____________________________________________________________________ ECHO. %_% ECHO.[~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~] ECHO.[ %C0%%L!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!%%C1% ] ECHO.[ %C0%%L!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!%%C1% ] ECHO.[ %C0%%L!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!%%C1% ] ECHO.[ %C0%%L!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!%%C1% ] ECHO.[ %C0%%L!!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!!%%C1% ] ECHO.[ %C0%%L!!!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!!!%%C1% ] ECHO.[ %C0%%L!!!!!!!%%C1% ] IF %VE%==TRUE ECHO.[ %C0%%L!!!!!!!%%C1% ] ECHO.[____________________________________________________________________] ECHO [ESC] To exit ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ IF %ANSI%==TRUE ECHO %ESC%[30m%ESC%[K%ESC%[0m%ESC%[A GOTO OUT :DGVE ECHO %%1 %% !@FBBC%ANSI% %% CALL %F% . GOTO:DGV C_2E . 0 0 0 0 0 0 0 0 0 0 1 8 1 8 0 0 CALL %F% . GOTO:DGV C0 0 3 C 6 6 6 E 7 E 7 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C1 1 1 8 3 8 1 8 1 8 1 8 1 8 7 E 0 0 CALL %F% . GOTO:DGV C2 2 3 C 6 6 0 6 0 C 1 8 3 0 7 E 0 0 CALL %F% . GOTO:DGV C3 3 3 C 6 6 0 6 1 C 0 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C4 4 0 C 1 C 3 C 6 C 7 E 0 C 0 C 0 0 CALL %F% . GOTO:DGV C5 5 7 E 6 0 7 C 0 6 0 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C6 6 1 C 3 0 6 0 7 C 6 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C7 7 7 E 0 6 0 C 1 8 3 0 3 0 3 0 0 0 CALL %F% . GOTO:DGV C8 8 3 C 6 6 6 6 3 C 6 6 6 6 3 C 0 0 CALL %F% . GOTO:DGV C9 9 3 C 6 6 6 6 3 E 0 6 0 C 3 8 0 0 CALL %F% . GOTO:DGV C_3A : 0 0 0 0 1 8 1 8 0 0 1 8 1 8 0 0 ECHO :OUT GOTO OUT :DGV SET S= %=% SET M=%4 IF %ANSI%==TRUE SET M=?SET C=! ECHO :%3 :DGL SET _= FOR %%_ IN (CALL SHIFT) DO %%_ %F% . GOTO:DGE %5 FOR %%_ IN (CALL SHIFT) DO %%_ %F% . GOTO:DGE %5 ECHO SET L%C%=%%L%C%%%%_% SET C=%C%! IF NOT %C%==!!!!!!!!! GOTO DGL ECHO GOTO OUT GOTO OUT :DGE IF %3==0 SET _=%_%%S%%S%%S%%S% IF %3==1 SET _=%_%%S%%S%%S%%M% IF %3==2 SET _=%_%%S%%S%%M%%S% IF %3==3 SET _=%_%%S%%S%%M%%M% IF %3==4 SET _=%_%%S%%M%%S%%S% IF %3==5 SET _=%_%%S%%M%%S%%M% IF %3==6 SET _=%_%%S%%M%%M%%S% IF %3==7 SET _=%_%%S%%M%%M%%M% IF %3==8 SET _=%_%%M%%S%%S%%S% IF %3==9 SET _=%_%%M%%S%%S%%M% IF %3==A SET _=%_%%M%%S%%M%%S% IF %3==B SET _=%_%%M%%S%%M%%M% IF %3==C SET _=%_%%M%%M%%S%%S% IF %3==D SET _=%_%%M%%M%%S%%M% IF %3==E SET _=%_%%M%%M%%M%%S% IF %3==F SET _=%_%%M%%M%%M%%M% GOTO OUT :RTIME FOR %%_ IN ( 0 1 2 3 4 5 6 7 8 9) DO IF ERRORLEVEL 1%%_ SET _=%_% %%_ CHOICE /C&&&&&&&&&0123456789>NUL IF ERRORLEVEL 10 GOTO RTIME ECHO SET _=%_% EXIT :OUT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

作者: electronixtar     时间: 2006-10-12 02:46
楼上的是一个纯DOS下的批处理时钟

作者: 3742668     时间: 2006-10-12 06:44
本主题亮点在顶楼的 ASCII code 部分。

作者: 不得不爱     时间: 2006-10-12 22:07
——————————————————版务纪录—————————————————— 执行:qwe1234567 说明:2 、3、4、5楼的帖子发到不相关的主题:[共同参与][挑战思路][批处理处理浮点运算] 操作:分割2 、3、4、5楼的帖子到这个主题上 提示:请不要把帖子发到不相关的主题上! ————————————————————————————————————————

作者: redtek     时间: 2006-10-13 00:37
顶~~

作者: amao     时间: 2006-10-14 15:19
Originally posted by needed at 2006-10-11 22:24: 我还是没有看懂,如果是借助外部命令的话,不用这么复杂. 如果只用内部命令,我看不到例子
在纯DOS下,如何借助外部命令,读取文件首行为变量? 我是新手,很想知道这个问题,还望赐教。

作者: hxuan999     时间: 2006-11-23 00:55
晕呀