-1

In a directory, I have a multiple .txt file. For example:

abc.txt
bcd.txt
def.txt

Now in each of these file I have credential information like:

Hostname: 10.87.99.09
username: qwerty
password: ytrewq

These are the content present in the each of the .txt files present in folder.

Now my requirement is that, I need to ask the user for the folder path and once user provide the folder path I need to take .txt file present in the folder one by one and then take the server credentials present in file assign it to one variable so that I can pass those variable to sqlcmd command to perform operation.

For example, hostname: 10.23.32.21, then a= 10.23.32.21 so that I can pass %a% to sqlcmd command.

As, I am newbie to batch script I have written some code by doing rnd:

@echo off
setlocal enableDelayedExpansion
set /p file="Please enter file Name: "
cd %file%
set /x ID=1

for /f "delims=" %%G in ('dir *.txt /b') do (
set filename[!ID!]=%%~G
for /f "tokens=1,2delims=: " %%a in ('findstr /n . %%~G') do set "name[%%a]=%%b"
set c= %name[1]%
echo%c%
set /x ID+=1
)

set filename
endlocal
pause

And getting output as:

Please enter file Name: C:\Users\LENOVO\Desktop\testing\multiple
The syntax of the command is incorrect.
ECHO is off.
The syntax of the command is incorrect.
ECHO is off.
The syntax of the command is incorrect.
ECHO is off.
The syntax of the command is incorrect.
filename[]=test.txt

I also tried so many things but not able to get the result. Can someone please help me with these? Thanks in advance!

saurabh704
  • 63
  • 6

2 Answers2

0
@ECHO OFF
setlocal enableDelayedExpansion
:again
set /p file="Please enter file Name: "
pushd "%file%"
if /i "%cd%" neq "%file%" echo Change directory failed&goto again
set /A ID=0
    
for /f "delims=" %%G in ('dir /b /a-d *.txt') do (
 set /A ID+=1
 set "filename[!ID!]=%%~G"
 for /f "tokens=1,2delims=: " %%a in (%%G) do if /i "%%a"=="hostname" set "name[!ID!]=%%b"
)

popd

set filename
set name

FOR /L %%c IN (1,1,%ID%) DO IF DEFINED name[%%c] ECHO file : !filename[%%c]! name !name[%%c]!

GOTO :EOF

Your set /x should be set /a, hence the syntax errors.

pushd saves the current directory and switches to the specified directory. popd returns to the original directory.

%cd% is set by the system to the current directory, so if the pushd failed, then the comparison will be Not EQual,the message will be produced and the user re-prompted. The /i makes the comparison case-insensitive.

If you start id at 0 instead of 1 then id will contain a count of the entries found.

Purely convention to specify dir options first. /o-d added to exclude any subdirectorynames that fit the filename mask *.txt.

Within the loop, simply read the file whose name is in %%G. Tokenise so that token 1 (%%a) is Hostname on the target line in the file and token 2 (%%b) is 10.87.99.09. Use if to select the appropriate line so it doesn't have to be the first, and set name[!ID!] to that value.

The problems with your code is that the findstr /n ... would produce a line of the form 1:Hostname: 10.87.99.09 so Token 1 would be 1, Token 2 Hostname and token 3 10.87.99.09 So you'd need to select tokens 1 and 3 not 1 and 2, and you'd be assuming that line 1 contained hostname.

Then there's set c= %name[1]%. Batch would set c to Space for this command because name[1] was undefined when the for...%%G.. was encountered. set c=!name[1]! would have done what you intended. See Stephan's DELAYEDEXPANSION link: https://stackoverflow.com/a/30284028/2128947

And for a similar reason, echo%c% would have been evaluated as echo, which is why you got the echo is off "error" report.

Use set "var1=data" for setting string values - this avoids problems caused by trailing spaces.

Finally, the for /L will list those filenames and names where the process found hostname in the file

When you use the point-click-and-giggle method of executing a batch, the batch window will close if a syntax-error is found or the script runs to completion. You should instead open a 'command prompt' and run your batch from there so that the window remains open and any (error) messages will be displayed.

Magoo
  • 77,302
  • 8
  • 62
  • 84
0

What follows is an alternative example, which should pick up only three lines, beginning with the case insensitive strings Hostname:, username:, and password:, in any order. It should create a variable, %args%, with an expanded value in the following format, (based upon your submitted example file): -S tcp:10.87.99.09 -U qwerty -P ytrewq

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

:AskFilePath
Set "file="
Set /P "file=Please provide the absolute or relative file path - %CD%>"
If Not Defined file GoTo AskFilePath
Set file 2>NUL | %SystemRoot%\System32\findstr.exe /RC:"[\?\*]" 1>NUL && (
    GoTo AskFilePath
)
For %%G In (
    "%file%"
) Do If "%%~aG" Lss "-" (
    GoTo AskFilePath
) Else If "%%~aG" GEq "d" GoTo AskFilePath

Set "args="
For /F "Tokens=1,* Delims=: " %%G In (
    'Type "%file%" 2^>NUL'
) Do If Not Defined args (
    If /I "%%G" == "Hostname" Set "args=-S tcp:%%H"
    If /I "%%G" == "username" Set "args=-U %%H"
    If /I "%%G" == "password" Set "args=-P %%H" 
) Else (
    SetLocal EnableDelayedExpansion
    For %%I In ("!args!") Do (
        EndLocal
        If /I "%%G" == "Hostname" Set "args=%%~I -S tcp:%%H"
        If /I "%%G" == "username" Set "args=%%~I -U %%H"
        If /I "%%G" == "password" Set "args=%%~I -P %%H"    
    )
)
If Not Defined args GoTo EndScript

Rem Your code goes here, [two demonstration lines given].
Set args
Pause

:EndScript
EndLocal
GoTo :EOF
Compo
  • 36,585
  • 5
  • 27
  • 39