Search for a list of words in a file, then find those words

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Search for a list of words in a file, then find those words

#1 Post by pditty8811 » 22 Feb 2013 17:41

I'd like to search for a list of words from an external list (simple each word on a line), and search for them in a file (C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg) (matching the whole word, even if it's inside another, and matching case), then if they are there find those words on another file(Campaign_SCR.mis.tmp) (matching the whole word even if its inside another, matching case) replacing the whole line in (Campaign_SCR.mis.tmp) with Name=ShipDummy ONLY if the line starts with "Name=". After that the two lines below that in that same file would be replaced with 2nd line "Class=ShipDummy", then 3rd line "Type=206".

Here is the code I have now. Now it searches for ClassName=Variable in C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg, then it replaces the whole line with Class=ShipDummy if it finds the variable in Campaign_SCR.mis.tmp. It also replaces 1 line below it with "Type=206".

BUT I'd like it to search for a name from a list I specify, search in (C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg). Then if it finds the match, then search for that in Campaign_SCR.mis.tmp and replace the whole line, only if that line starts with "Name=", with Name=ShipDummy. The two lines below that would be replaced with 2nd line "Class=ShipDummy", then 3rd line "Type=206":

Code: Select all

Name=ShipDummy
Class=ShipDummy
Type=206


**Please keep in mind that within Campaign_SCR.mis.tmp the variable's line wont often appear as Name=variable. It is likely to be Name=(words)variable(words)

Can the list that is searched be external? Can we make it search one word per line. For exmaple: if the list is as follows:

Bismarck Hood Repulse

It will search for each word.**

When it matches the words from the list to (C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg) please ensure that it matches case as well. So "Bismarck" from list will find "Bismarck" from (C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg), and not find "bismarck"
setlocal enableDelayedExpansion

Code: Select all

>Campaign_SCR.mis.tmp (
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" Campaign_SCR.mis.backup') do (
    ( echo !ln!| findstr "^Type=12$" >NUL && set ln=ln ) || (
        set "ln=%%B"
        if "!ln:~0,6!"=="Class=" (
            findstr /s /c:"ClassName=!ln:~6!" "C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR\*.clg" >"C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR\null" && (
                echo Class=ShipDummy
                set "ln=Type=12"
            )
        )
        if #!ln!==# (echo;) else echo !ln!
    )
  )
)


Thank you for your time!

By the way, this may be a simpler workaround to the problem I have here: How do I apply this?

So for example:

Say I have an external list (call it List.txt for example) that looks like this:

Code: Select all

Bismarck
Hood
Repulse


I will search C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg for that. Say it finds "Bismarck" and "Hood" in this:

Code: Select all

sadfasfasfdBismarckfasdfasdfasdfas

asdfasfdafHoodasdfasfas

Then it will search Campaign_SCR.mis.tmp for Bismarck and Hood replacing:

Code: Select all

Name=asdfBismarckasfdw
Class=jlkjf
Type=12

With:

Code: Select all

Name=ShipDummy
Class=ShipDummy
Type=206


And

Code: Select all

Name=asdfHoodasfdw
Class=jlkjf
Type=13


With:

Code: Select all

Name=ShipDummy
Class=ShipDummy
Type=206

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Almost!

#2 Post by pditty8811 » 22 Feb 2013 21:17

I have the following code, but it seems to be applying error :EOF at the end of Campaign_SCR.mis.tmp (Campaign_SCR.mis.tmp.NEW). It does change one of the words found in Text.txt but that is it. Then it adds :EOF to the end of Campaign_SCR.mis.tmp

How can I fix this sod all words in Text.txt will be changed to Name=ShipDummy etc... in Campaign_SCR.mis.tmp


Code: Select all

    setlocal EnableDelayedExpansion

    REM INITIALIZE THE LIST OF WORDS THAT WILL BE SEARCHED
    set targetWords=:EOF

    rem I'd like to search for a list of words from an external list (simple each word on a line)
    for /F %%a in (List.txt) do (   
    rem and search for them in a file (C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR\*.clg)
    findstr "%%a" "C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR\*.clg" > NUL
    rem if they are there...
    if !errorlevel! equ 0 (
      REM INSERT THE WORD IN THE TARGET LIST
      set targetWords=!targetWords! %%a
     )
    )

    REM INSERT THE END-OF-FILE MARK IN THE FILE
    echo :EOF>> Campaign_SCR.mis.tmp

    REM INITIALIZE THE NUMBER OF LAST PROCESSED LINE IN REDIRECTED Campaign_SCR.mis.tmp
    set lastLine=0

    rem ... find those words on another file(Campaign_SCR.mis.tmp)
    < Campaign_SCR.mis.tmp (for /F "delims=:" %%a in ('findstr /N "%targetWords%"             Campaign_SCR.mis.tmp') do (
    REM DUPLICATE PREVIOUS LINES UNTIL NEW TARGET LINE
    set /A numOfLines=%%a-lastLine-1
    for /L %%i in (1,1,!numOfLines!) do (
      set line=
      set /P line=
      echo(!line!
    )
    rem if the line starts with "Name="
    set /P line=
    if "!line:~0,5!" equ "Name=" (
      rem replacing the whole line...with Name=ShipDummy
      echo Name=ShipDummy
      rem After that the two lines below that in that same file would be replaced with 2nd line "Class=ShipDummy",
      set /P line=
      echo Class=ShipDummy
      rem then 3rd line "Type=206".
      set /P line=
      echo Type=206
      set /A lastLine=%%i+2
    ) else (
      REM DUPLICATE THE NON MATCHING LINE, IF IS NOT THE :EOF MARK
      if "!line!" neq ":EOF" (
         echo !line!
         set lastLine=%%i
      )
     )
      )) > Campaign_SCR.mis.tmp.NEW

    REM UPDATE THE NEW FILE
    REM del Campaign_SCR.mis.tmp
    REM ren Campaign_SCR.mis.tmp.NEW Campaign_SCR.mis.tmp





**Basically, I'd like to do this:**

Say I have an external list (call it List.txt for example) that looks like this:

Code: Select all

    Bismarck
    Hood
    Repulse


I will search C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg for that. Say it finds "Bismarck" and "Hood" in this:

Code: Select all

    sadfasfasfdBismarckfasdfasdfasdfas

    asdfasfdafHoodasdfasfas


Then it will search Campaign_SCR.mis.tmp for Bismarck and Hood replacing:

Code: Select all

    Name=asdfBismarckasfdw
    Class=jlkjf
    Type=12


With:

Code: Select all

    Name=ShipDummy
    Class=ShipDummy
    Type=206


And

Code: Select all

    Name=asdfHoodasfdw
    Class=jlkjf
    Type=13

With:

Code: Select all

    Name=ShipDummy
    Class=ShipDummy
    Type=206



**But instead I'm getting:**

Code: Select all

     Name=ShipDummy     <------------used to be Name=asdfBismarckasfdw
     Class=ShipDummy
     Type=206 

     Name=asdfHoodasfdw
     Class=jlkjf
     Type=13

    :EOF
    :EOF



Would it also be possible to remove the :EOF?

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Search for a list of words in a file, then find those wo

#3 Post by foxidrive » 22 Feb 2013 22:10

pditty8811 wrote:Say I have an external list (call it List.txt for example) that looks like this:

Code: Select all

Bismarck
Hood
Repulse


I will search C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg for that. Say it finds "Bismarck" and "Hood" in this:

Code: Select all

sadfasfasfdBismarckfasdfasdfasdfas

asdfasfdafHoodasdfasfas

Then it will search Campaign_SCR.mis.tmp for Bismarck and Hood replacing:

Code: Select all

Name=asdfBismarckasfdw
Class=jlkjf
Type=12

With:

Code: Select all

Name=ShipDummy
Class=ShipDummy
Type=206


And

Code: Select all

Name=asdfHoodasfdw
Class=jlkjf
Type=13


With:

Code: Select all

Name=ShipDummy
Class=ShipDummy
Type=206


This seems to work but it leaves lines 2/3 in Campaign_SCR.mis.tmp so you have to remove them.
It uses GnuSED.

As we don't know the real makeup of the files then this is a start.


Code: Select all

@echo off
for /f "delims=" %%a in (list.txt) do (
findstr "%%a" "C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg" >nul
if not errorlevel 1 (
find "%%a" < "Campaign_SCR.mis.tmp" >nul && (
sed "s/^Name=.*%%a.*/Name=ShipDummy\nClass=ShipDummy\nType=206/" "Campaign_SCR.mis.tmp" > "Campaign_SCR.mis.tmp.tmp2"
move "Campaign_SCR.mis.tmp.tmp2"  "Campaign_SCR.mis.tmp" >nul
)
)
)
pause

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#4 Post by pditty8811 » 22 Feb 2013 22:24

Very nice. But it pushes the other lines down, as you said. How to prevent this?

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#5 Post by pditty8811 » 22 Feb 2013 22:39

Perhaps this code can help? It replaces the lines instead of moving them down. But the other specifics are different.

Code: Select all

>Campaign_SCR.mis.tmp (
for /f "tokens=1* delims=:" %%A in ('findstr /n "^" Campaign_SCR.mis.backup') do (
    ( echo !ln!| findstr "^Type=206$" >NUL && set ln=ln ) || (
        set "ln=%%B"
        if "!ln:~0,6!"=="Class=" (
            findstr /s /c:"ClassName=!ln:~6!" "C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR\*.clg" >"C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR\null" && (
                echo Class=ShipDummy
                set "ln=Type=206"
            )
        )
        if #!ln!==# (echo;) else echo !ln!
    )
  )
)

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#6 Post by pditty8811 » 22 Feb 2013 22:45

I'd like to prevent the lines from moving down, as its game files. I'd like to add your name to the mod I'm building if that's OK.

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Search for a list of words in a file, then find those wo

#7 Post by foxidrive » 22 Feb 2013 22:52

You can add another section to remove the extra lines.

The trouble is that I doubt that what you've posted is what is really inside the file, and with batch files we often use the actual position and actual words inside the file to help locate the position.

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#8 Post by pditty8811 » 22 Feb 2013 22:53

I'll post an example. 1 sec.

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#9 Post by pditty8811 » 22 Feb 2013 22:54

Here is a snippet of Campaign_SCR.tmp :

Code: Select all



[Mission]
Title=
MissionType=0
MissionDataType=1
Year=1940
Month=6
Day=1
Hour=14
Minute=0
Fog=0
FogRand=0
Clouds=1
CloudsRand=0
Precip=0
PrecipRand=0
WindHeading=0
WindSpeed=5.000000
WindRand=0
WeatherRndInterval=5
SeaType=0
Briefing=

[Group 1]
GroupName=Schleswig-Holstein Aug 39
CommandUnitName=SMS Schleswig Holstein#2
Category=0
RandStartRadius=0.000000
DeleteOnLastWaypoint=true
EvolveFromEntryDate=false

[Group 1.Unit 1]
Name=SMS Schleswig Holstein#2
Class=SchlwHolst
Type=10
Origin=German
Side=0
Commander=0
CargoExt=-1
CargoInt=-1
CfgDate=19380101
DeleteOnLastWaypoint=true
DockedShip=false
GameEntryDate=19390825
GameEntryTime=1
GameExitDate=19390830
GameExitTime=1
EvolveFromEntryDate=false
Long=1219919.000000
Lat=6522396.000000
Height=0.000000
Heading=11.909902
Speed=5.000000
CrewRating=3
DelayMin=0
ReportPosMin=-1
ReportPosProbability=100
RandStartRadius=0.000000
NextWP=0

[Group 1.Unit 1.Waypoint 1]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1220367.000000
Lat=6524318.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 2]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1222727.000000
Lat=6526578.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 3]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1223507.000000
Lat=6526658.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 4]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1225547.000000
Lat=6531298.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 5]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1251000.000000
Lat=6551900.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 6]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1325500.000000
Lat=6557600.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 7]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1375000.000000
Lat=6538600.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 8]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1434000.000000
Lat=6529000.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 9]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1608000.000000
Lat=6590000.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 10]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=1826000.000000
Lat=6562000.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 11]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=2275000.000000
Lat=6647000.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 12]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=2322000.000000
Lat=6562200.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 13]
Speed=15.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=2295050.000000
Lat=6545550.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 14]
Speed=5.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=2247650.000000
Lat=6534350.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 15]
Speed=5.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=2238860.000000
Lat=6532000.000000
Height=0.000000

[Group 1.Unit 1.Waypoint 16]
Speed=5.000000
Radius=0.000000
Loop=-1
LoopProbability=100
Long=2238140.000000
Lat=6530340.000000
Height=0.000000

[Group 1.Unit 2]
Name=Flottenbegleiter Class#1
Class=Ftboot
Type=3
Origin=German
Side=0
Commander=0
CargoExt=-1
CargoInt=-1
CfgDate=19380101
DeleteOnLastWaypoint=true
DockedShip=false
GameEntryDate=19390825
GameEntryTime=1
GameExitDate=19451231
GameExitTime=0
EvolveFromEntryDate=false
Long=1219668.875000
Lat=6521210.000000
Height=0.000000
Heading=11.909902
Speed=5.000000
CrewRating=3
DelayMin=0
ReportPosMin=-1
ReportPosProbability=100
RandStartRadius=0.000000

[Group 1.Unit 3]
Name=Type 34 Class#1
Class=DDType34
Type=4
Origin=German
Side=0
Commander=0
CargoExt=-1
CargoInt=-1
CfgDate=19380101
DeleteOnLastWaypoint=true
DockedShip=false
GameEntryDate=19390825
GameEntryTime=1
GameExitDate=19451231
GameExitTime=0
EvolveFromEntryDate=false
Long=1220169.125000
Lat=6523582.000000
Height=0.000000
Heading=11.909902
Speed=5.000000
CrewRating=3
DelayMin=0
ReportPosMin=-1
ReportPosProbability=100
RandStartRadius=0.000000

[Group 2]
GroupName=Schleswig-Holstein Apr 40
CommandUnitName=SMS Schleswig Holstein#6
Category=0
RandStartRadius=0.000000
DeleteOnLastWaypoint=true
EvolveFromEntryDate=false

[Group 2.Unit 1]
Name=SMS Schleswig Holstein#6
Class=SchlwHolst
Type=10
Origin=German
Side=2
Commander=0
CargoExt=-1
CargoInt=-1
CfgDate=19380101
DeleteOnLastWaypoint=true
DockedShip=false
GameEntryDate=19400408
GameEntryTime=2307
GameExitDate=19451201
GameExitTime=0
EvolveFromEntryDate=false
Long=1186520.000000
Lat=6536400.000000
Height=0.000000
Heading=80.573151
Speed=14.000000
CrewRating=3
DelayMin=0
ReportPosMin=-1
ReportPosProbability=100
RandStartRadius=0.000000
NextWP=0
Last edited by pditty8811 on 22 Feb 2013 23:00, edited 1 time in total.

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#10 Post by pditty8811 » 22 Feb 2013 22:57

Notice:

Name=
Class=
Type=

at the top of every section of a unit. "Name=" will always be preceded by a line in brackets (brackets are precedeb by 1 blank line, and the blank line is preceded by another section of a unit or waypoints)

and "Type=" will always be followed by "Origin="


Notice "GroupName=" too. I don't want Name= to replace GroupName=, I'd like Name= to ony replace a line that begins with Name=, and of course is in List.txt and the other file.
Last edited by pditty8811 on 22 Feb 2013 23:18, edited 5 times in total.

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#11 Post by pditty8811 » 22 Feb 2013 22:58

Thank you for your efforts

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Search for a list of words in a file, then find those wo

#12 Post by foxidrive » 22 Feb 2013 23:24

Try this.


Code: Select all

@echo off
for /f "delims=" %%a in (list.txt) do (
findstr "%%a" "C:\Users\P Ditty\Documents\SH3\data\cfg\Backups_SCR*.clg" >nul
if not errorlevel 1 (
find "%%a" < "Campaign_SCR.mis.tmp" >nul && (
sed "s/^Name=.*%%a.*/Name=ShipDummy\nClass=ShipDummy\nType=206/" "Campaign_SCR.mis.tmp" > "Campaign_SCR.mis.tmp.tmp2"
call :stripdup "Campaign_SCR.mis.tmp.tmp2" "Campaign_SCR.mis.tmp" "(Class=.*\nType=.*)\nClass=.*\nType=.*" "$1"
del "Campaign_SCR.mis.tmp.tmp2"
)
)
)
pause
goto :EOF

:stripdup

::Search and replace
@echo off
if "%~3"=="" (
echo.Search and replace
echo Syntax:
echo %0 "filein.txt" "fileout.ext" "regex" "replace_text" [first]
echo.
echo. if [first] is present only the first occurrence is changed
goto :EOF
)
if "%~5"=="" (set global=true) else (set global=false)
set s=regex.replace(wscript.stdin.readall,"%~4")
 >_.vbs echo set regex=new regexp
>>_.vbs echo regex.global=%global%
>>_.vbs echo regEx.IgnoreCase=True           
>>_.vbs echo regex.pattern="%~3"
>>_.vbs echo wscript.stdOut.write %s%
cscript /nologo _.vbs <"%~1" >"%~2"
del _.vbs

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#13 Post by pditty8811 » 22 Feb 2013 23:24

foxidrive wrote:You can add another section to remove the extra lines.

The trouble is that I doubt that what you've posted is what is really inside the file, and with batch files we often use the actual position and actual words inside the file to help locate the position.



What do you mean add another section?

Sorry, I'm learning and noobish. But I've learned alot over the past 3 days!

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Search for a list of words in a file, then find those wo

#14 Post by foxidrive » 22 Feb 2013 23:33

See the batch file I posted just above your last post. It adds another bit that removes the unwanted lines.

pditty8811
Posts: 184
Joined: 21 Feb 2013 15:54

Re: Search for a list of words in a file, then find those wo

#15 Post by pditty8811 » 22 Feb 2013 23:38

foxidrive wrote:See the batch file I posted just above your last post. It adds another bit that removes the unwanted lines.

I don't think its working.

Post Reply