Batch file that retrieves the string of file1 from file2
file1.txt
aaa.dll
ccc.dll
ddd.sys
file2.txt
aaa.dll=c:\windows\aaa.dll
bbb.dll=c:\windows\bbb.dll
ccc.dll=c:\windows\system32\ccc.dll
ddd.sys=c:\windows\system32\drivers\ddd.sys
eee.log=c:\windows\debug\wia\eee.log
expected result
c:\windows\aaa.dll
c:\windows\system32\ccc.dll
c:\windows\system32\drivers\ddd.sys
test command
for /f "tokrns=*" %%i ('findstr file1.txt file2.txt') do (set result=%%i)
I am assuming that file2.txt is, essentially, a list of "configuration settings"... that is, a list of name-value pairs. Further, file1.txt is a list of names that you want to get the values of.
If that is the case, then you need to run the findstr command for each of the lines in file1.txt. For instance:
getvalues.bat
#echo off
setlocal
set "REQUIRED=file1.txt"
set "SETTINGS=file2.txt"
for /f "usebackq tokens=*" %%a in ( "%REQUIRED%" ) do (
for /f "tokens=1,* delims==" %%b in ( 'findstr /b "%%a=" "%SETTINGS%"' ) do (
echo %%c
)
)
produces the following:
C:\>getvalues.bat
c:\windows\aaa.dll
c:\windows\system32\ccc.dll
c:\windows\system32\drivers\ddd.sys
Notes
I've hard-coded REQUIRED (the list of names to get values for) and SETTINGS (the list of name-value pairs). Depending on your requirements, you could take one or more from the command-line.
The first loop runs over all lines in REQUIRED (=file1.txt). It uses usebackq because the filename is wrapped in double-quotes, just in case it contains spaces.
For each name from the first loop (%%a), we run a findstr command. The /b tells it to look for the pattern at the beginning of the line. I also append an = to the end of the name. Both help prevent accidental partial-matches.
The tokens=1,* delims== splits the output of findstr at the first (or only) equals-sign. The name (before the =) will be assigned to %%b and the value (all the rest) will be assigned to %%c.
You don't need to compare anything in order to get strings (that is, variable values) that have been defined previously:
#echo off
setlocal EnableDelayedExpansion
rem Define the strings from file2.txt
for /F "delims=" %%a in (file2.txt) do set "%%a"
rem Retrieve the strings indicated in file1.txt
for /F %%a in (file1.txt) do echo !%%a!
If you insist in using the "find strings" way:
for /F "tokens=2 delims==" %%a in ('findstr /G:file1.txt file2.txt') do echo %%a
Related
I have been searching through StackOverflow but could not find an answer that hits the mark. I have 2 .txt files to compare and return a 3rd one where differences exist.
However, only the first column of the first 2 files need a comparison.
E:\Compare_flie\file_1.txt
GND ZERO
22XC44 XXYYZZ
33XC55 YYUUTT
E:\Compare_file\file_2.txt
GND ZERO
22XC44 KK77UU
33XC55 88JJ66
66NN77 HHOO99
99CC88 UU77RR
E:\Compare_file\file_3.txt (intended output)
66NN77 HH0099
99CC88 UU77RR
Tried the code below but it is only good at picking out the differences of all the strings in the line
%echo on
findstr /v /i /g:E:\Compare_files\file_1.txt E:\Compare_files\file_2.txt
> E:\Compare_files\file_3.txt
Refined it further but not hitting the mark yet.
%echo on
for /f "tokens=1 delims= " %%I in ("E:\Compare_files\file_1.txt") do
findstr /v /i "%%I"/g:"D:\Compare_files\file_2.txt"
> "D:\Compare_files\file_3.txt"
Appreciate if anyone can assist.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir"
SET "destdir=U:\destdir"
SET "filename1=%sourcedir%\q48816766.txt"
SET "filename2=%sourcedir%\q48816766_2.txt"
SET "tempfile=%temp%\q48816766.tmp"
SET "outfile=%destdir%\outfile.txt"
(FOR /f "usebackq" %%a IN ("%filename1%") DO ECHO %%a )>"%tempfile%"
FINDSTR /b /v /g:"%tempfile%" "%filename2%">"%outfile%"
REM DEL "%tempfile%" /F /Q
GOTO :EOF
I've set up names to suit my system, but with the two files containing your data.
Obviously, the usebackq on the for/f is only required if the filename is quoted. The parentheses around the command permit the echoed output to be accumulated into the temporary file. What's important here is the space between the %%a and ). This ensures that the temporary file contains trailing spaces.
Then apply the temporary file to the second data file via /g as in OP's code. The presence of the trailing spaces in the tempfile ensure that the only lines selected for omission are those where the first column exactly matches so for instance had 66NN7 appeared in the first file, first column, then this would not match 66NN77 in the second file.
Here's a method using batch with the type command piping the first file's contents over to the findstr command then passing the arguments accordingly to redirect those results into a temp file.
Using a for /f loop with "usebackq tokens=1 delims= " it will iterate through the temp file and for each line in that file parsing accordingly, it will append the column one lines with an echo command using >> to redirect the results over to file_3.txt with the expected results.
Please note the addition of the if exist "%srcdir%\file_3.txt" del /q /f "%srcdir%\file_3.txt" to delete that file if it exists since the for /f echo commands will append one after the other to it.
#echo on
set srcdir=E:\Compare_files
set tmpfile=%temp%\%~N0.tmp
type "%srcdir%\file_1.txt" | findstr /vig:"%srcdir%\file_2.txt">"%tmpfile%"
if exist "%srcdir%\file_3.txt" del /q /f "%srcdir%\file_3.txt"
for /f "usebackq tokens=1 delims= " %%I in ("%tmpfile%") do (
echo %%~I>>"%srcdir%\file_3.txt"
)
Further Resources
FOR /F
FOR /?
usebackq - specifies that the new semantics are in force,
where a back quoted string is executed as a
command and a single quoted string is a
literal string command and allows the use of
double quotes to quote file names in
file-set.
Redirection
Comparing/finding the difference between two text files using findstr
As I understand your problem, you want the lines from file_2.txt whose first column are not contained in first column of file_1.txt, that is: file_2.txt minus file_1.txt. There is a simpler approach to get such result:
#echo off
setlocal
rem Fill "line" array with lines from file_2.txt
rem use the first column for the array keys
for /F "delims=" %%a in (file_2.txt) do for /F %%b in ("%%a") do set "line[%%b]=%%a"
rem Delete array elements with same key from file_1.txt
for /F %%b in (file_1.txt) do set "line[%%b]="
rem Show remaining elements
(for /F "tokens=1* delims==" %%a in ('set line[') do echo %%b) > file_3.txt
folks!
I'm not sure if this is a very simple task or a very complicated one, but either way I'm struggling with it. Suppose I have a text file like this:
11111FOO
11111BAR
22222ZOOM
33333FOO
11111CAR
I want to figure out a command line in windows that I can plop into a batch file that will pull out text strings from this file and push them to a new file. I would pass in the leading string to search for, and it would take everything from the end of that string to the next new line.
So using the above example, if I said the leading string was 11111, I would get a new text file that looked like this:
FOO
BAR
CAR
Everything else would be ignored.
Thanks!
If there are no potential poison characters in the input file then perhaps this would suffice:
#(For /F "UseBackQ Delims=" %%A In ("input.txt") Do #(Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do #Call Echo %%an:*%%B=%%))>"output.txt"
Magoo's additions:
#Echo Off
(For /F "UseBackQ Delims=" %%A In ("q46858215.txt") Do (Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do Call Echo %%an:*%%B=%%))>"Output1.txt"
If "%~1"=="" GoTo :Next
(For /F "Delims=" %%A In ('FindStr/BLC:"%~1" "q46858215.txt"') Do (
Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do Call Echo %%an:*%%B=%%))>"Output2.txt"
:Next
(For /F "UseBackQ Delims=" %%A In ("q46858215.txt") Do (Set "an=%%A"
For /L %%B In (%%A 1 %%A) Do Echo %%B))>"Output3.txt"
I used a file named q46858215.txt containing OP's data for my testing.
Produces three output files:
Output1.txt : Compo's original
Output2.txt : filtered to isolate lines beginning with (first parameter to routine)
Output3.txt : Compo's original in reverse, showing the numbers isolated
I have a simple for loop in a batch file I'm working on but I can't get the variables to expand correctly. the whole script is below..
setlocal enabledelayedexpansion
set track=0
FOR /f "tokens=2" %%G IN ('find "PhysicalTrackNumber" %1') DO if %track% LSS %%G set track=%%G
echo %track%
echo %1
pause
The for command pulls all the rows with the physical track number and I'm just trying to get the biggest number. IT always stays 0 though when it's comparing. I've tried with !! around my variable as well but then the script seems to do something completely different. I thought it would take the new variable.
What am I missing to compare the outputs to the previous and just get the biggest number?
find "string" filename output consists of
an empty line;
a string of 10 dashes followed by the filename being searched line;
any matching lines of text in the file.
Use skip=2 option (a number of lines to skip at the beginning):
FOR /f "skip=2 tokens=2" %%G IN ('find "PhysicalTrackNumber" "%~1"') DO (
if !track! LSS %%G set "track=%%~G"
)
As an alternative, use findstr instead of find:
FOR /f "tokens=2" %%G IN ('findstr "PhysicalTrackNumber" "%~1"') DO (
if !track! LSS %%G set "track=%%~G"
)
I need to write a batch script which pleases a user about filenames.
For example, a user launches the .bat file, selects option "delete files", the script waits for filenames and next the user writes it in one line like file1.txt file2.txt file3.txt file4.txt.
How can I grab the filenames like array elements to use it later?
setlocal EnableDelayedExpansion
:deleteFiles
set /P "filenames=Enter file names to delete: "
rem Grab filenames in an array
set n=0
for %%a in (%filenames%) do (
set /A n+=1
set "filename[!n!]=%%~a"
)
rem For example, to process the filenames:
for /L %%i in (1,1,%n%) do (
echo %%i- !filename[%%i]!
)
The list of filenames must be separated by spaces (or commas, or semicolons); if a name include spaces, it must be enclosed in quotes.
For further information about arrays, see this post.
version without delayed expansion:
#ECHO OFF &SETLOCAL
set "filepattern=*.txt"
for /f "tokens=1*delims=:" %%a in ('dir /b /a-d "%filepattern%"^|findstr /n $') do (
set "filename[%%a]=%%~b"
)
for /f "tokens=2delims==" %%a in ('set "filename"') do (
echo "%%~a"
)
I have two .properties files as follows
first.properties second.properties
----------------- ---------------------
firstname=firstvalue fourthname=100100
secondname=secondvalue sixthname=200200
thirdname=thirdvalue nineththname=ninethvalue
fourthname=fourthvalue tenthname=tenthvalue
fifthname=fifthvalue
sixthname=sixthvalue
seventhname=seventhvalue
i want to compare two files with the names and need to remove common name and corresponding value from first.properties. The output file should be as
third.properties.
------------------
firstname=firstvalue
secondname=secondvalue
thirdname=thirdvalue
fifthname=fifthvalue
seventhname=seventhvalue
i used the following code,but it is giving Cartesian product scenario.can you please help me out to achieve the above.
for /F "tokens=1,2 delims==" %%E in (first.properties) do (
for /F "tokens=1,2 delims==" %%G in (second.properties) do (
if "%%E" NEQ "%%G" echo %%E=%%F>>!HOME!\Properties\third.properties
)
)
try this:
#echo off
(for /f "delims==" %%i in (second.properties) do echo(%%i.*)>temp.properties
findstr /rvg:temp.properties first.properties>third.properties
del temp.properties
..output in third.properties is:
firstname=firstvalue
secondname=secondvalue
thirdname=thirdvalue
fifthname=fifthvalue
seventhname=seventhvalue
at the request of the OP I add a (much slower) solution without a temp file:
#echo off
(for /f "tokens=1,2delims==" %%i in (first.properties) do findstr /r "%%i.*" second.properties >nul||echo(%%i=%%j)>third.properties
type third.properties
The Batch file below does not create temporary files nor use external commands (like findstr.exe), so it run faster.
#echo off
setlocal EnableDelayedExpansion
rem Create list of names in second file
set "secondNames=/"
for /F "delims==" %%a in (second.properties) do set "secondNames=!secondNames!%%a/"
rem Copy properties of first file that does not appear in second one
(for /F "tokens=1* delims==" %%a in (first.properties) do (
if "!secondNames:/%%a/=!" equ "%secondNames%" (
echo %%a=%%b
)
)) > third.properties
I used a slash to delimit property names. If this character may appear in the names, just select a different one in the program.
Previous solution eliminate any exclamation mark from the files; this detail may be fixed, if needed.