Welcome guest. Before posting on our computer help forum, you must register. Click here it's easy and free.

Author Topic: Batch Variable Line Selector  (Read 13786 times)

0 Members and 1 Guest are viewing this topic.

la3

    Topic Starter


    Greenhorn

    • Experience: Beginner
    • OS: Windows 10
    Batch Variable Line Selector
    « on: May 21, 2020, 08:06:21 AM »
    I am trying to create a batch file that can select a single line by choice out of a text file and then use those variables only on that line... My objective is to take something like the following -

    Code: [Select]
    Variable1 Variable2 Variable3 Variable4
    Description1 ComputerName1 ComputerUser1 ComputerPassword1
    Description2 ComputerName2 ComputerUser2 ComputerPassword2
    Description3 ComputerName3 ComputerUser3 ComputerPassword3
    Description4 ComputerName4 ComputerUser4 ComputerPassword4
    Description5 ComputerName5 ComputerUser5 ComputerPassword5
    Description6 ComputerName6 ComputerUser6 ComputerPassword6

    And then use it for creating something that would look like this -


    Code: [Select]
    Variable1's listed from text file -

    Description1
    Description2
    Description3
    Description4
    Description5
    Description6

    Make a selection: ((User enters Variable1))

    cmdkey /generic:"<line1variable2>" /user:"<line1variable3>" /pass:"<line1variable4>" <-------from a specific line a user selects
    mstsc /v:"<line1variable2>" /f <-------from a specific line a user selects


    Any help would be greatly appreciated...

    Sidewinder



      Guru

      Thanked: 139
    • Experience: Familiar
    • OS: Windows 10
    Re: Batch Variable Line Selector
    « Reply #1 on: May 21, 2020, 12:03:41 PM »
    Batch language is truly ugly. That said, the batch logic here is to create an in-memory array (of sorts), let the user make a selection and then create the parameters for the cmdkey and mstsc commands.

    Code: [Select]
    @echo off
    setlocal enabledelayedexpansion
    set x=0

    for /f "skip=1 tokens=1-4" %%i in (%~dp0\Choices.txt) do (
      call set /a x+=1
      call set item.%%x%%.1=%%i
      call set item.%%x%%.2=%%j
      call set item.%%x%%.3=%%k
      call set item.%%x%%.4=%%l
    )

    for /l %%i in (1,1,%x%) do (
      call echo %%i. !item.%%i.1!
    )

    echo. & set /p sel=Enter Selection:

    cmdkey /generic:"!item.%sel%.2!>" /user:"!item.%sel%.3!" /pass:"!item.%sel%.4!"
    mstsc /v:"!item.%sel%.2!" /f

    The batch file uses a file named Choices.txt for it's input. The name is negotiable, just be sure to change the batch file accordingly.

    The descriptions, computername, computeruser and computerpassword fields cannot contain any embedded spaces or special characters. This is not negotiable.

    Hope this gives you some ideas
    The true sign of intelligence is not knowledge but imagination.

    -- Albert Einstein

    la3

      Topic Starter


      Greenhorn

      • Experience: Beginner
      • OS: Windows 10
      Re: Batch Variable Line Selector
      « Reply #2 on: May 22, 2020, 07:28:41 AM »
      I had been trying my hand at this from Google to hacking up other code I found and just couldn't get it to work so flawlessly as what you've provided. Such a small amount of code in comparison... This is perfect, thank you!

      I do have a request though -- This worked for what I originally needed it to but I had another idea to process a CSV file in a similar way. This CSV file stores every computer name a user has logged in to, what I need is for it to read the file from the bottom and only got up 9 lines. Any ideas on accomplishing that?

      Batch language is truly ugly. That said, the batch logic here is to create an in-memory array (of sorts), let the user make a selection and then create the parameters for the cmdkey and mstsc commands.

      Code: [Select]
      @echo off
      setlocal enabledelayedexpansion
      set x=0

      for /f "skip=1 tokens=1-4" %%i in (%~dp0\Choices.txt) do (
        call set /a x+=1
        call set item.%%x%%.1=%%i
        call set item.%%x%%.2=%%j
        call set item.%%x%%.3=%%k
        call set item.%%x%%.4=%%l
      )

      for /l %%i in (1,1,%x%) do (
        call echo %%i. !item.%%i.1!
      )

      echo. & set /p sel=Enter Selection:

      cmdkey /generic:"!item.%sel%.2!>" /user:"!item.%sel%.3!" /pass:"!item.%sel%.4!"
      mstsc /v:"!item.%sel%.2!" /f

      The batch file uses a file named Choices.txt for it's input. The name is negotiable, just be sure to change the batch file accordingly.

      The descriptions, computername, computeruser and computerpassword fields cannot contain any embedded spaces or special characters. This is not negotiable.

      Hope this gives you some ideas

      Sidewinder



        Guru

        Thanked: 139
      • Experience: Familiar
      • OS: Windows 10
      Re: Batch Variable Line Selector
      « Reply #3 on: May 22, 2020, 09:21:51 AM »
      First up, I tweaked yesterday's post and fixed a typo. Added is code to check the user selection input is within the range of the selections and the typo is on the cmdkey line where there is an extra '>' symbol. Corrected code below:

      Code: [Select]
      @echo off
      setlocal enabledelayedexpansion
      set x=0

      for /f "skip=1 tokens=1-4" %%i in (%~dp0\Choices.txt) do (
        call set /a x+=1
        call set item.%%x%%.1=%%i
        call set item.%%x%%.2=%%j
        call set item.%%x%%.3=%%k
        call set item.%%x%%.4=%%l
      )

      for /l %%i in (1,1,%x%) do (
        call echo %%i. !item.%%i.1!
      )

      echo. & set /p sel=Enter Selection:
      if %sel% GTR %x% echo Selection Out Of Range & goto :eof
      if %sel% LSS 1 echo Selection Out Of Range & goto :eof

      echo cmdkey /generic:"!item.%sel%.2!" /user:"!item.%sel%.3!" /pass:"!item.%sel%.4!"
      echo mstsc /v:"!item.%sel%.2!" /f

      Today's question is much like yesterday's. You could read the file into an array and then read the array from high index to low. The code below uses the choices.txt file and displays the last 3 lines.

      Code: [Select]
      @echo off
      setlocal enabledelayedexpansion

      set x=0
      for /f "skip=1 tokens=*" %%i in (%~dp0\Choices.txt) do (
        call set /a x+=1
        call set item.!x!=%%i
      )

      :: The 2 in the set statement should be one less than the number of lines you want to process
      ::
      set /a lower=%x%-2
      for /l %%i in (%x%, -1, %lower%) do (
        call echo !item.%%i!
      )

      Note: This might not be practical if the input file is large. Are you familiar with any other languages like VBScript or Powershell?

      This should get you started.
      The true sign of intelligence is not knowledge but imagination.

      -- Albert Einstein

      strollin



        Adviser
      • Thanked: 84
        • Yes
      • Certifications: List
      • Computer: Specs
      • Experience: Guru
      • OS: Windows 10
      Re: Batch Variable Line Selector
      « Reply #4 on: May 22, 2020, 10:58:28 AM »
      Instead of having the user enter the description (which is highly prone to errors from typos and such), why not assign a number to each description and ask the user to enter the number that corresponds to the description?

      la3

        Topic Starter


        Greenhorn

        • Experience: Beginner
        • OS: Windows 10
        Re: Batch Variable Line Selector
        « Reply #5 on: May 22, 2020, 11:01:30 AM »
        In the end, that is the way the script was ultimately made to be thanks to Sidewinder!

        Instead of having the user enter the description (which is highly prone to errors from typos and such), why not assign a number to each description and ask the user to enter the number that corresponds to the description?

        la3

          Topic Starter


          Greenhorn

          • Experience: Beginner
          • OS: Windows 10
          Re: Batch Variable Line Selector
          « Reply #6 on: May 22, 2020, 11:03:22 AM »
          I did catch that typo though it wasn't seemingly hurting anything. I did take a VBScript class in college... It's been a long time and the knowledge wasn't retained well. I have been dabbling in Powerscript... I learned a lot more about batch scripts in school and really just hack around... I don't do a lot of coding, just 1. bored from quarantine and 2. saw a need for some simplification on some of the things we do here.

          I've modified what you've provided me and it's working as intended but the numbers aren't 1, 2, 3, 4, etc.... On the file I'm parsing now they numbers are 55, 54, 53, etc... Assumingly the 55th line of the file. Anyway to fix that? Here's what I've got -

          What I plan on trying though if you have a better way great! - Export the last 9 lines to another temp file and parse that file then delete the file on close... Not actually sure off the top of my head on how to do that but back to Google while waiting your reply! Thanks!

          Code: [Select]
          @echo off
          setlocal enabledelayedexpansion
          set x=0

          for /f "skip=1 tokens=1-1 delims=," %%i in (%1) do (
            call set /a x+=1
            call set item.%%x%%.1=%%i
          )

          set /a lower=%x%-8
          for /l %%i in (%x%, -1, %lower%) do (
            call echo %%i. !item.%%i.1!
          )

          echo. & set /p sel=Enter Selection:
          if %sel% GTR %x% echo Selection Out Of Range & goto :eof
          if %sel% LSS 1 echo Selection Out Of Range & goto :eof

          echo !item.%sel%.1!



          First up, I tweaked yesterday's post and fixed a typo. Added is code to check the user selection input is within the range of the selections and the typo is on the cmdkey line where there is an extra '>' symbol. Corrected code below:

          Code: [Select]
          @echo off
          setlocal enabledelayedexpansion
          set x=0

          for /f "skip=1 tokens=1-4" %%i in (%~dp0\Choices.txt) do (
            call set /a x+=1
            call set item.%%x%%.1=%%i
            call set item.%%x%%.2=%%j
            call set item.%%x%%.3=%%k
            call set item.%%x%%.4=%%l
          )

          for /l %%i in (1,1,%x%) do (
            call echo %%i. !item.%%i.1!
          )

          echo. & set /p sel=Enter Selection:
          if %sel% GTR %x% echo Selection Out Of Range & goto :eof
          if %sel% LSS 1 echo Selection Out Of Range & goto :eof

          echo cmdkey /generic:"!item.%sel%.2!" /user:"!item.%sel%.3!" /pass:"!item.%sel%.4!"
          echo mstsc /v:"!item.%sel%.2!" /f

          Today's question is much like yesterday's. You could read the file into an array and then read the array from high index to low. The code below uses the choices.txt file and displays the last 3 lines.

          Code: [Select]
          @echo off
          setlocal enabledelayedexpansion

          set x=0
          for /f "skip=1 tokens=*" %%i in (%~dp0\Choices.txt) do (
            call set /a x+=1
            call set item.!x!=%%i
          )

          :: The 2 in the set statement should be one less than the number of lines you want to process
          ::
          set /a lower=%x%-2
          for /l %%i in (%x%, -1, %lower%) do (
            call echo !item.%%i!
          )

          Note: This might not be practical if the input file is large. Are you familiar with any other languages like VBScript or Powershell?

          This should get you started.

          Sidewinder



            Guru

            Thanked: 139
          • Experience: Familiar
          • OS: Windows 10
          Re: Batch Variable Line Selector
          « Reply #7 on: May 22, 2020, 12:43:46 PM »
          The numbers you see are not the record number in the file, but the index of the record in the array (there is no array type in batch code, but in can be implemented). They are off by one because the first record in the file was a header and consequently skipped. Not sure why you need a temp file; all the records are in the array so there is no need to write records to a file and then read them back.

          What is the final result you're looking for? I'm thinking once we know where we're going, it'll be easier to find a way there.

          The following code does nothing more than create a 3 record CSV file from the original posted data file (delimited by tabs):

          Code: [Select]
          @echo off
          setlocal enabledelayedexpansion

          set x=0
          for /f "skip=1 tokens=*" %%i in (%~dp0\Choices.txt) do (
            call set /a x+=1
            call set item.!x!=%%i
          )

          :: The 2 in the set statement should be one less than the lines to process
          ::
          set /a lower=%x%-2
          if exist %~dp0\Tempfile.txt del %~dp0\Tempfile.csv

          for /l %%i in (%x%, -1, %lower%) do (
            for /f "tokens=1-4" %%a in ("!item.%%i!") do (
              echo %%a,%%b,%%c,%%d >> %~dp0\Tempfile.csv
            )
          )

          Till next time


          The true sign of intelligence is not knowledge but imagination.

          -- Albert Einstein

          la3

            Topic Starter


            Greenhorn

            • Experience: Beginner
            • OS: Windows 10
            Re: Batch Variable Line Selector
            « Reply #8 on: May 22, 2020, 12:49:13 PM »
            I have placed this batch file in the Send To area of the context menu so I can right click a CSV file and Send To the batch file for processing. When I do this on a user who's been around awhile here's the output of the script -

            Code: [Select]
            627. CCTSCLC0009586
            626. CCTSCLC0009472
            625. CCTSCLC0009472
            624. CCTSCLC0009472
            623. CCTSCLC0009533
            622. CCTSCLC0009416
            621. CCTSCLC0009265
            620. CCTSCLC0009586
            619. CCTSCLC0009586

            Enter Selection:

            BUT What I would like it to be for simplicity is

            Code: [Select]
            1. CCTSCLC0009586
            2. CCTSCLC0009472
            3. CCTSCLC0009472
            4. CCTSCLC0009472
            5. CCTSCLC0009533
            6. CCTSCLC0009416
            7. CCTSCLC0009265
            8. CCTSCLC0009586
            9. CCTSCLC0009586

            Enter Selection:

            The numbers could even be backwards if necessary but I would like 1-9 or 9-1 and not 600+.

            The numbers you see are not the record number in the file, but the index of the record in the array (there is no array type in batch code, but in can be implemented). They are off by one because the first record in the file was a header and consequently skipped. Not sure why you need a temp file; all the records are in the array so there is no need to write records to a file and then read them back.

            What is the final result you're looking for? I'm thinking once we know where we're going, it'll be easier to find a way there.

            The following code does nothing more than create a 3 record CSV file from the original posted data file (delimited by tabs):

            Code: [Select]
            @echo off
            setlocal enabledelayedexpansion

            set x=0
            for /f "skip=1 tokens=*" %%i in (%~dp0\Choices.txt) do (
              call set /a x+=1
              call set item.!x!=%%i
            )

            :: The 2 in the set statement should be one less than the lines to process
            ::
            set /a lower=%x%-2
            if exist %~dp0\Tempfile.txt del %~dp0\Tempfile.csv

            for /l %%i in (%x%, -1, %lower%) do (
              for /f "tokens=1-4" %%a in ("!item.%%i!") do (
                echo %%a,%%b,%%c,%%d >> %~dp0\Tempfile.csv
              )
            )

            Till next time
            « Last Edit: May 22, 2020, 12:59:22 PM by la3 »

            Sidewinder



              Guru

              Thanked: 139
            • Experience: Familiar
            • OS: Windows 10
            Re: Batch Variable Line Selector
            « Reply #9 on: May 22, 2020, 02:34:17 PM »
            I kept most of the original code, but changed the approach to the solution. The lines are counted in the input file, then there are calculations to determine how many records are not needed and how many to keep. This cuts down the size of the array although the numbering scheme can be a bit unnerving. There is no temp file. I have localized the file for your environment, but you may want to check the use of the %1 variable.

            Code: [Select]
            @echo off
            :: -------------------------------------------------------------
            ::  Script:   Choices
            ::  Author:   Sidewinder
            ::  Date:     05/21/2020
            ::  Comment:  Computer Hope
            ::  Update:   
            :: -------------------------------------------------------------
            setlocal enabledelayedexpansion
            set x=0
            set y=0
            set keep=9

            for /f "tokens=1* delims=:" %%i in ('findstr /n /r ".*" "%1"') do (
              set tLines=%%i > nul
            )
            set /a nokeep=%tlines%-%keep%

            for /f "tokens=1-4 delims=," %%i in (%1) do (
              call set /a y+=1
              if !y! GTR %nokeep% (
                call set /a x+=1
                call set item.%%x%%.1=%%i
                call set item.%%x%%.2=%%j
                call set item.%%x%%.3=%%k
                call set item.%%x%%.4=%%l
              )
            )

            for /l %%i in (1,1,%x%) do (
              call echo %%i. !item.%%i.1!
            )

            echo. & set /p sel=Enter Selection:
            if %sel% GTR %x% echo Selection Out Of Range & goto :eof
            if %sel% LSS 1 echo Selection Out Of Range & goto :eof

            cmdkey /generic:"!item.%sel%.2!" /user:"!item.%sel%.3!" /pass:"!item.%sel%.4!"
            mstsc /v:"!item.%sel%.2!" /f

            Good luck.

            The true sign of intelligence is not knowledge but imagination.

            -- Albert Einstein