1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

HELP with finding Length of String in BATCH file

Discussion in 'Windows - Software discussion' started by aweathe, May 28, 2007.

  1. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    Hello,

    I realize there are alot of solutions out there in google for finding the length of a string using a batch file. I have tried to understand 3 different ones listed, and was unsuccessful. I have placed a copy of one of the scripts I found through google below. Could someone explain/help me understand it? Or give me a new solution that they can explain better?

    here is one solution: (and listed just below is what I don't understand)
    @echo off
    set test_=Testing the length of a string
    echo:..%test_%>tmp$$$.txt
    for %%i in (1 2 3 4 5 6 7 8) do echo 1234567890>>tmp$$$.txt
    dir tmp$$$|find "TMP$$$ TXT">tmp$$$2.bat
    echo set lenght_=%%2>tmp$$$.bat
    call tmp$$$2
    echo set length_=%%%lenght_%>tmp$$$.bat
    call tmp$$$
    for %%f in (tmp$$$*.*) do if exist %%f del %%f
    echo %test_%
    echo length_=%length_%
    set length_=

    What I don't understand:
    1. Why "$$$" is used, and what does it mean?
    2. Why "%%%" is used, and what does it mean?
    3. The line starting with "echo set length" (ie: what is this: "%%%lenght_%" ?).
    4. The last line. (it seems like it's not finished.)

    Thank you for any help!
     
  2. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    Hi, aweathe, I read this a couple of days ago, but I balked at trying to explain that awful batch file to you!!!

    It must have been written before about 1990, because it relies on certain features of early MS-DOS. The DIR command for example is completely different. The $$$ is just an old convention for naming temp files. The file seems to work by creating another batch file and calling it. The triple percent signs are because to echo one percent sign which is a special character in DOS, you need to put two in the echo statement. echo %% will actually result in % appearing on screen or in a file. To get two in a file, you need three in the batch which makes the file.

    Finally, set variable= just deletes "variable" from the environment, thus saving the space it occupied. Very important in early DOS where you only had 256 bytes to play with.

    That file is an awful example of how NOT to write a batch file. No REMs to explain things. Horrid.

    I modestly feel that this following is more like it!

    The question kept nagging at me. I have seen all kinds of complex bits of jiggery-pokery to achieve this aim. Today I had a burst of lateral thinking and came up with this

    It works by echoing the string whose length is to be counted to a temp text file. Each byte in the file represents one character. The echo process adds two bytes, one for a carriage return, one for a line feed. So you find the file size, then subtract 2, which gives you the number of characters in the string

    @echo off
    setlocal enabledelayedexpansion

    REM for testing purposes
    set /p string="string ? "

    REM write string to temp text file
    REM put redirection symbol right after
    REM variable to avoid a trailing space
    echo %string%> %temp%\string.txt

    REM get the file size in bytes
    for %%a in (%temp%\string.txt) do set /a length=%%~za

    REM do some batch arithmetic
    REM subtract 2 bytes, 1 for CR 1 for LF
    set /a length -=2

    echo string "%string%" has %length% characters

    REM clean up temp file
    del %temp%\string.txt

    [pre]
    REM These two lines are all you need
    REM Before, the variable "str" holds the string
    REM After, the variable "len" holds its length

    echo %str%> "%temp%\st.txt"
    for %%a in (%temp%\st.txt) do set /a len=%%~za & set /a len -=2 & del "%temp%\st.txt"
    [/pre]

     
  3. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    Hey it's Indochine!

    Thanks once again for another SUPER-CLEAR response!

    I'm just trying to fit the code into what I want to do. Just one question. In the line you wrote:

    for %%a in (%temp%\string.txt) do set /a length=%%~za

    is the ~z part at the end standard to find the size of the file?

    thanks.
     
    Last edited: May 31, 2007
  4. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    Yes it is. If you get a file's name into a FOR variable,

    the following will yield information about the file

    Assume the variable is %%I

    Use single % sign on command line, double (%%) in batch file

    NB the modifiers are CASE SENSITIVE so %%~z is OK, but %%~Z will fail

    (My remarks in brackets)

    %~I - expands %I removing any surrounding quotes
    %~fI - expands %I to a fully qualified path name

    %~dI - expands %I to a drive letter only (Actually, a letter and a colon eg D:

    %~pI - expands %I to a path only
    %~nI - expands %I to a file name only
    %~xI - expands %I to a file extension only (a dot and an extension eg .txt)

    %~sI - expanded path contains short names only
    %~aI - expands %I to file attributes of file
    %~tI - expands %I to date/time of file
    %~zI - expands %I to size of file (in bytes)

    The modifiers can be combined to get compound results:

    %~dpI - expands %I to a drive letter and path only
    %~nxI - expands %I to a file name and extension only
    %~fsI - expands %I to a full path name with short names only
    %~ftzaI - expands %I to a DIR like output line


    By the way you don't actually need this line although I put it in

    [pre]setlocal enabledelayedexpansion[/pre]
     
    Last edited: May 31, 2007
  5. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    Hmm I'm running into a bit of a block due to my lack of understanding. You're script is working fine for me, and is not the problem. I'm trying to use your script in my batch file: I am placing your script within a couple of nested for loops, and I'm having trouble. In particular, the line

    for %%a in (%temp%\string.txt) do set /a length=%%~za

    is producing an error "Missing operand". I've been trying to play around with it using !'s ect. But without any luck. Can you think of anything for this?


    Another thing I don't understand, and may be what I need to know to solve the problem, is why the line you wrote:

    echo %string%> %temp%\string.txt

    works. Whereas the lines:

    topfolder =%CD%
    echo %string%> %topfolder%\string.txt

    do not. In other words the line you wrote using the %temp% file creates a string.txt there, but the 2 lines i wrote don't create the string.txt file. Can you tell me why? I wanted to be able to follow the code more easily to debug/understand what's going on.


    Many thanks!!
     
    Last edited: May 31, 2007
  6. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    I don't want you to have to look at it, but it may make it easier for you to understand my problem if I post the full script here. If it doesn't make it easier for you, then I'm more than happy to ask a few more 'short and specific' questions (like the last post) until I get it working.

    If you like, here is the code:

    @echo off

    SETLOCAL ENABLEDELAYEDEXPANSION

    set topfolder=%CD%

    rem if exist delete text1.txt and text2.txt
    echo deleting files text files if exist...
    pause

    if exist "%topfolder%\text1.txt" del "%topfolder%\text1.txt" > nul
    if exist "%topfolder%\text2.txt" del "%topfolder%\text2.txt" > nul

    pause

    dir /b /ad> text1.txt

    pause

    echo entering into FOR loop...
    pause

    for /F "delims==" %%G in ('type "%topfolder%\text1.txt"') do (

    cd %topfolder%
    echo %%G>> text2.txt

    pause

    cd %topfolder%\%%G
    dir /b /ad > "%topfolder%\temp.txt"

    for /f "delims==" %%H in ('type "%topfolder%\temp.txt"') do (

    set string=test
    rem set string=%%G
    set string

    echo %topfolder%

    if exist "%topfolder%\string.txt" del "%topfolder%\string.txt" > nul
    pause

    REM write string to temp text file
    REM put redirection symbol right after
    REM variable to avoid a trailing space

    echo !string!> %topfolder%\string.txt
    echo check sting.txt contents here
    pause

    REM get the file size in bytes
    for %%a in ('type "%topfolder%\string.txt"') do (set /a length=%%~za)

    set length
    pause

    REM do some batch arithmetic
    REM subtract 2 bytes, 1 for CR 1 for LF

    echo !length!
    echo !string!
    pause

    set /a length -=2

    echo string "!string!" has !length! characters
    pause

    Rem if !length! GTR 6 (cd %topfolder% & echo %%H>> text2.txt)

    REM clean up temp file
    rem del %temp%\string.txt


    Rem cd %topfolder%
    Rem echo %%H>> text2.txt
    )
    )

    del "%topfolder%\temp.txt" > nul

    echo end of program
    pause
     
  7. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    aweathe, I just saw this before going to bed, I'll have a look at it tomorrow - looks interesting... what is it meant to do? Mi'm sure between us we can wrestle it into submission!

     
  8. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    It seems you want to examine some subdirectories and find filenames longer than 6 characters and write those names to a file?

    I have hacked your code about so that it works, but you seem to have lost interest, so maybe you have moved on.

    Surely the full path name of each file would be more useful?
     
  9. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    Indochine, I have certainly not lost interest! Sorry for the lack of replies for the last few days.. i was meeting a friend in another city, and we did more 'site seeing' than anything else.

    Yes your interpretation is correct: the code is meant to write out a list of folder names to a text file. (not the full path names)

    There are a set of folders in the directory I'm running the file from. And in each of these folders there are a different set of folders. I would like to write out the names of the higher level folders followed by a list of their sub-level folder names that are longer than a 6 characters. IE: a long continuous list of file names that I can just copy into excel.. and then format.

    you said you've hacked the code to make it work?? I'd love to see it! :O)
     
    Last edited: Jun 5, 2007
  10. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    did you mean six characters including the dot and extension? (That was how it appears; not sure if that is your intention. If the extension is always the same that would simplify things.

    If you clarify re. the above, I'll see if I can make the code do the desired and post it here for you.

    Hope you had a nice trip...


     
  11. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    No that's not what I meant... my explanation was not very clear...

    There is no need for any extensions because I'm only after the folder names, not any file names.

    The folders are set up like this:

    Folder1
    subfoldera
    subfolderb
    subfolderc
    Folder2
    subfoldera
    subfolderb
    subfolderc
    Folder3
    subfoldera
    subfolderb
    subfolderc

    And I would like to write the folder names to a text file, just as is shown above in the list. I would like each of the 'toplevel' folder names written (ie "Folder1, Folder2, ect.) but only the 'subfolder' names written that are longer than 6 characters.

    did this make it any clearer?!
     
  12. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    OK... are the folders just like that - two levels of nesting?
     
  13. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
  14. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    [pre]
    @echo off
    SETLOCAL ENABLEDELAYEDEXPANSION
    set topfolder=%CD%
    if exist "%topfolder%\report.txt" del "%topfolder%\report.txt" > nul
    for /F "delims==" %%G in ('dir /b /ad') do (
    echo %%G>> %topfolder%\report.txt
    cd %topfolder%\%%G
    for /f "delims==" %%H in ('dir /b /ad') do (
    set string=%%H
    set /a length=0
    echo !string!> %topfolder%\string.txt
    for %%a in (%topfolder%\string.txt) do (set /a length=%%~za)
    set /a length -=2
    if !length! GTR 6 echo %%H>> %topfolder%\report.txt
    )
    )
    cd %topfolder%
    type report.txt
    echo end of program

    [/pre]

    I have called it qqq5.bat.

    here is the folder layout, topfolder is f:\test\qqq

    [pre]
    F:\test\qqq>dir /s /b /ad
    F:\test\qqq\folder1
    F:\test\qqq\folder2
    F:\test\qqq\folder3
    F:\test\qqq\folder1\subfolderA
    F:\test\qqq\folder1\subfolderB
    F:\test\qqq\folder2\subfolderC
    F:\test\qqq\folder2\subfolderD
    F:\test\qqq\folder3\subfolderE
    F:\test\qqq\folder3\subfolderF
    [/pre]

    and this is what I see when I run it...

    [pre]
    F:\test\qqq>qqq5.bat
    folder1
    subfolderA
    subfolderB
    folder2
    subfolderC
    subfolderD
    folder3
    subfolderE
    subfolderF
    end of program[/pre]
     
    Last edited: Jun 5, 2007
  15. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    I get the same error, "missing operand" from the line:

    for %%a in (%topfolder%\string.txt) do (set /a length=%%~za)

    I also don't see the text files 'report.txt' and 'string.txt' created when I refresh the topfolder, while in a 'pause' in the program in the command prompt. I should see these files even though they're in a for loop, right?

     
  16. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    That means that it is processing a blank. What happens if you include this line after the @echo off at the top?

    setlocal enableextensions

    I am running the batch from folder qqq in this folder arrangement under Windows XP Professional Service Pack 2 with Command Extensions enabled.

    [​IMG]

    diagnostic version
    output...
     
    Last edited: Jun 5, 2007
  17. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    Still the same problems: 1) the results.txt file and string.txt files are not created at any point.
    2) I'm getting the Missing operand error a whole lot. Here is the output from using a copy of your latest code:


    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder>excelwritertext2
    .bat

    subfolders under this folder...
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1\foldera
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1\folderb
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1\folderc
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2\foldera
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2\folderb
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2\folderc
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3\foldera
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3\folderb
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3\folderc

    found folder folder1
    found folder foldera
    testing folder name "foldera " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folderb
    testing folder name "folderb " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folderc
    testing folder name "folderc " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folder2
    found folder foldera
    testing folder name "foldera " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folderb
    testing folder name "folderb " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folderc
    testing folder name "folderc " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folder3
    found folder foldera
    testing folder name "foldera " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folderb
    testing folder name "folderb " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    found folder folderc
    testing folder name "folderc " for length
    Missing operand.
    Missing operand.
    Missing operand.
    Missing operand.
    finished processing

    results...
    The system cannot find the file specified.

    end of program
     
    Last edited: Jun 5, 2007
  18. Indochine

    Indochine Regular member

    Joined:
    Dec 21, 2006
    Messages:
    1,447
    Likes Received:
    0
    Trophy Points:
    46
    try this version

     
  19. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    well it didn't work unfortunately. I'm looking at it right now and will post again soon. Here's the output anyways, before I post:

    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder>excelwritertest3
    .bat

    subfolders under this folder...
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1\foldera
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1\folderb
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder1\folderc
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2\foldera
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2\folderb
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder2\folderc
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3\foldera
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3\folderb
    C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder\folder3\folderc

    The system cannot find the path specified.
    found folder and Settings\ANDREW\Desktop\EventData2\string.txt
    The system cannot find the path specified.
    The system cannot find the path specified.
    The system cannot find the path specified.
    found folder and Settings\ANDREW\Desktop\EventData2\string.txt
    testing folder name " and Settings\ANDREW\Desktop\EventData2\string.txt " for le
    ngth
    echoing and Settings\ANDREW\Desktop\EventData2\string.txt to file C:\Documents
    and Settings\ANDREW\Desktop\EventData2\test folder \string.txt
    file length is 117 bytes
    file length is bytes
    Missing operand.
    file length is bytes
    Missing operand.
    file length is bytes
    Missing operand.
    file length is bytes
    Missing operand.
    subtracting 2
    result is 115
    it is more than 6 so echo and Settings\ANDREW\Desktop\EventData2\string.txt to
    "C:\Documents and Settings\ANDREW\Desktop\EventData2\test folder \report.txt"
    The system cannot find the path specified.
    The system cannot find the file and.
    The system cannot find the file and.
    finished processing

    results...
    The system cannot find the file specified.

    end of program
     
  20. aweathe

    aweathe Member

    Joined:
    May 9, 2007
    Messages:
    55
    Likes Received:
    0
    Trophy Points:
    16
    I think i have it working...(!) just doing double checks. The problem was the directory was too long... (why i don't know (?))

    When using the version of the code you sent me first(below) it all seems to work.


    @echo off
    setlocal enableextensions
    SETLOCAL ENABLEDELAYEDEXPANSION

    set topfolder=%CD%


    if exist "%topfolder%\report.txt" del "%topfolder%\report.txt" > nul

    for /F "delims==" %%G in ('dir /b /ad') do (
    echo %%G>> %topfolder%\report.txt
    cd %topfolder%\%%G

    for /f "delims==" %%H in ('dir /b /ad') do (
    set string=%%H
    set /a length=0
    echo !string!> %topfolder%\string.txt

    for %%a in (%topfolder%\string.txt) do (

    set /a length=%%~za)

    set /a length -=2

    if !length! GTR 3 echo %%H>> %topfolder%\report.txt

    )
    )

    cd %topfolder%
    type report.txt
    echo end of program


     

Share This Page