|
Answer» Hi,
I've searched everywhere without luck for the answer to how to escape a double quote as a delimiter in the for /F "tokens=1* delims=:\=" etc command syntax. All the delimiters currently listed are valid and work, but the " is also used as a delimiter in the input file, and I can't figure out how to include it in my delimiters.
Thanks, in ADVANCE, KarenI tried using the escape character (^) but the for command choked and spit it back out. Any chance you can use %~ notation to remove the quotes from a token.
This would be easier if we could see your code and a sample of the data.
Here is the script:
for /F "usebackq tokens=1-6 delims=:\=" %%A in ( `findstr /C:"\"ORACLE_HOME\"=" c:\temp\tns_loc.txt` ) do ( set drvltr=%%B REM set drvltr=%drvltr:~2,1% (this didn't work. the " confuses it) set dir4=%%F echo %%B %%C %%D %%E %%F echo %%B %drvltr% echo %%F %dir4% )
Here is the record in the file: "ORACLE_HOME"="C:\\oracle\\product\\10.2.0\\client_1"
Here is the current output: "C oracle product 10.2.0 client_1" "C <--- Notice, %drvltr% is blank client_1" client_1"
The first token is ignored. The second token comes up as "C and the sixth token comes up as client_1". I need to find a way to strip the ", and the set var doesn't work. So, I thought if I could specify the " as a delimiter, I could remove it that way. However, because the double quote is used to contain the tokens option syntax, I have to escape it somehow. I tried doubling up on the double quote "", but that made no difference. The normal escape character \ is already specified as a delimiter and it's working fine. Okay. I've decided I'm losing my mind. The following code works consistently and properly when you execute it from the command line: set drvltr="C set drvltr2=%drvltr:~1% set drv drvltr="C drvltr2=C
When I run the same code in a bat file two times in a row (with no changes at all): Execution one: (new session) C:\temp>( set drvltr="C set drvltr2=~1 set dir4=client_1" echo "C oracle product 10.2.0 client_1" echo "C echo client_1" ) "C oracle product 10.2.0 client_1" "C client_1"
C:\temp>set dr drvltr="C drvltr2=~1
Execution two: (same session) C:\temp>( set drvltr="C set drvltr2=C set dir4=client_1" echo "C oracle product 10.2.0 client_1" echo "C ~1 echo client_1" client_1" ) "C oracle product 10.2.0 client_1" "C ~1 client_1" client_1"
C:\temp>set dr drvltr="C drvltr2=C
Why would it take two executions to result in the variable having the proper value? I figured it out, finally:
I moved the second set and the echo statements out of the for loop:
for /F "usebackq tokens=1-6 delims=:\=" %%A in ( `findstr /C:"\"ORACLE_HOME\"=" c:\temp\tns_loc.txt`) do ( set drvltr=%%B set dir4=%%F )
set drvltr2=%drvltr:~1%
echo %%B %%C %%D %%E %%F echo %%B %drvltr2% echo %%F %dir4%
However, since the possiblity exists that this file will have more than one oracle_home record in it and I need to process both, I have to find some way to manage this. Perhaps by executing a sub-routine outside the loop and then returning into the loop?
Sometimes it's easier to break down the task rather than do everything at once.
Code: [Select]echo off for /F "tokens=1-2 delims==" %%A in ('findstr "ORACLE_HOME" c:\temp\tns_loc.txt') do ( echo drive: %%~dB echo path: %%~pB echo file: %%~nB for /f "tokens=1-5 delims=\" %%I in ("%%~B") do ( echo drive: %%I echo top level: %%J echo subfolder: %%K echo subfolder: %%L echo file: %%M ) )
Good luck. Here is the final code: It works on single and multiple records in the file.
REM retrieve all subkeys for the ORACLE installation from the REM Windows registry and subset entries with "ORACLE_HOME" REM to a temp file
regedit /e c:\temp\tns_location.txt "HKEY_LOCAL_MACHINE\Software\ORACLE" find "ORACLE_HOME" c:\temp\tns_location.txt > c:\temp\tns_loc.txt
REM there are header rows in the file REM read through the rows in the resulting file until we reach the row that has data in it REM test the record to see if it has data REM parse the record for the data values we seek
for /F "tokens=1-4 delims=/- " %%S in ('date/T') do set DATE=%%V%%T%%U
echo %DATE%
echo "for loop"
for /F "usebackq tokens=1-6 delims=:\=" %%A in ( `findstr /C:"\"ORACLE_HOME\"=" c:\temp\tns_loc.txt`) do ( set drvltr=%%B set dir1=%%C set dir2=%%D set dir3=%%E set dir4=%%F
echo %%B %%C %%D %%E %%F echo %drvltr% %dir1% %dir2% %dir3% %dir4% )
set drvltr2=%drvltr:~1%: echo %drvltr2% %dir1% %dir2% %dir3% %dir4% set ORACLE_HOME=%drvltr2%\%dir1%\%dir2%\%dir3%\%dir4% ECHO %ORACLE_HOME% cd %ORACLE_HOME%\NETWORK\ADMIN copy tnsnames.ora tnsnames.ora.bkp%DATE% copy c:\temp\tnsnames.ora %ORACLE_HOME%\NETWORK\ADMIN
:eofWhy not use the = as the delimiter and dequote each token using the ~ modifier?
Since the 2nd token appears to be a valid path you can use the ~d ~p ~n modifiers to get the drive letter, path and folder name if you want those
Code: [Select]for /f "tokens=1,2 delims==" %%S in (token.txt) do ( echo token 1 is %%S echo token 2 is %%T echo dequoted token 1 is %%~S echo dequoted token 2 is %%~T echo drive letter is %%~dT echo path is %%~pT echo name is %%~NT )
Token.txt
Code: [Select]"ORACLE_HOME"="C:\\oracle\\product\\10.2.0\\client_1" Code output
Code: [Select]token 1 is "ORACLE_HOME" token 2 is "C:\\oracle\\product\\10.2.0\\client_1" dequoted token 1 is ORACLE_HOME dequoted token 2 is C:\\oracle\\product\\10.2.0\\client_1 drive letter is C: path is \oracle\product\10.2.0\ name is client_1
Well, actually, client_1 is the lowest folder in the path name, but that's not a huge ISSUE.
I guess EITHER way would work. But I was slogging through this without any help to speak of, and that's what I came up with.
Quote from: kscarroll54 on November 14, 2008, 12:07:35 PM Well, actually, client_1 is the lowest folder in the path name, but that's not a huge issue.
It is the folder name, the last element in the full path, and is extracted using the ~n variable modifier, which is called the "name" modifier in the FOR documentation.
|