Perl/batch to find unique values and replace 2 lines of code

August 21, 2018 at 16:32:34
Specs: Windows 7
I currently have a perl script where I can take a new model and replace a certain line of code associated with a culvert feature in an old model thus saving out a new model with the new features. I can get it to replace 1 line for each feature, but I can't get it to replace 2 lines for each feature. Any help would be appreciated.

I need to find and replace 2 lines of code related to culverts in a model text file. I have a model with all the lines in the right order with the OLD culvert values, and another text file with the NEW culvert values but in the wrong order. What the script does currently:

1. In the model, finds line beginning with text "Connection Culv". This is the line of text I need to replace.

2. Finds the next line after "Connection Culv" that starts with "Conn Culvert Barrel" - this is the unique identifier for the replacement.

3. Pulls new values of "Connection Culv" from text file and replaces them in model.

4. Repeats for all instances of Connection Culv and then saves new file.</p>

Instead of ONLY replacing the line that begins with "Connection Culv" I need it to replace that line and the following line ( 111 111, 222 222, etc), but I can't get it to work.</p>

EXAMPLE:

MODEL IN CORRECT ORDER:
Connection Culv=This is Line1
111 111
Conn Culvert Barrel=Culvert1
*
Connection Culv=This is Line2
222 222
Conn Culvert Barrel=Culvert2
*
Connection Culv=This is Line3
333 333
Conn Culvert Barrel=Culvert3
*


REPLACEMENT TEXT FILE:
Connection Culv=This is Line3 - New text here
333 333 This should be new too
Conn Culvert Barrel=Culvert3
*
Connection Culv=This is Line1 - New text here
111 111 This should be new too
Conn Culvert Barrel=Culvert1
*
Connection Culv=This is Line2 - New text here
222 222 This should be new too
Conn Culvert Barrel=Culvert2
*

CURRENT RESULT:
Connection Culv=This is Line1 - New text here
111 111
Conn Culvert Barrel=Culvert1
*
Connection Culv=This is Line2 - New text here
222 222
Conn Culvert Barrel=Culvert2
*
Connection Culv=This is Line3 - New text here
333 333
Conn Culvert Barrel=Culvert3
*

NEEDED RESULT:
Connection Culv=This is Line1 - New text here
111 111 This should be new too
Conn Culvert Barrel=Culvert1
*
Connection Culv=This is Line2 - New text here
222 222 This should be new too
Conn Culvert Barrel=Culvert2
*
Connection Culv=This is Line3 - New text here
333 333 This should be new too
Conn Culvert Barrel=Culvert3
*

There are hundreds of these replacements that need to be made throughout the model. I feel like this should be simple, but nothing has worked. Here is the code I have currently that works for replacing the single line "Connection Culv" but not the following line. Any help is appreciated. Thanks.

Perl Script For First Half
# HEC-RAS Replacement Perl Script
# This will find and replace values in the HEC-RAS geometry file for modified culvet barrels. The process is:
# 1. In existing model file (HECRAS_Ex.txt) find where there is a "Connection Culv" (this is the line that needs to be replaced)
# 2. It then down for the next Conn Culvert Barrel line (this is the unique identifier)
# 3. It then takes from the new culvert file (culvNEW.txt) the new "Connection Culv" line and replaces it in the existing HECRAS_Ex.txt file.
# 4. Repeats for all and then saves out Output_HECRAS.txt

# Nomenclature for running Perl Script:
# C:\MyDir> perl PERL_SCRIPT.pl culvNEW.txt HECRAS_Ex.txt OutPut_HECRAS.txt

# Read Existing HEC-RAS Geometry File (HECRAS_Ex) with Old Culvert Connection Attributes
open (TEMPLATE, @ARGV[1]) or die;
@HECRAS_Ex = <TEMPLATE>;
close TEMPLATE;

# Read New Culvert Data File (culvNEW) with new Connection culvert Attributes
open (TEMPLATE, @ARGV[0]) or die;
@culvNEW = <TEMPLATE>;
close TEMPLATE;

for ($i=0; $i<@HECRAS_Ex; $i++) {

# only check lines starting with "Connection Culv" in the HECRAS_Ex file
if ($HECRAS_Ex[$i] =~ /^Connection Culv/) {
#print $HECRAS_Ex[$i];
#look for Connection Culv backwards
$iback=$i-1;
while ($HECRAS_Ex[$iback] !~ /^Conn Culvert Barrel/) {
$iback=$iback+1;
}
$local0=$HECRAS_Ex[$iback];
chomp($local0);
# print $HECRAS_Ex[$iback];
for ($j=0; $j<@culvNEW; $j++) {
# for ($j=0; $j<1; $j++) {
$local = $culvNEW[$j];
chomp($local);
# print $local;
# Remove the trailing new line
# chomp $local;
# print ($local eq $HECRAS_Ex[$iback]);
if ($local =~ /^$local0/) {
# print "match";
$jforward=$j-1;
while ($culvNEW[$jforward] !~ /^Connection Culv/) {
$jforward=$jforward-1;
}
# print $culvNEW[$jforward];
# Perform substitutions of LG card
$HECRAS_Ex[$i]=$culvNEW[$jforward];
# print $HECRAS_Ex[$i];
}
}
}
}
#write out the Geometry File based on the HECRAS_Ex file structure and the new values in the culvNEW file
open (OUT, ">" . @ARGV[2]) or die;
# Write output
print OUT @HECRAS_Ex;
# Close OUT
close OUT;

message edited by oryan


See More: Perl/batch to find unique values and replace 2 lines of code

Reply ↓  Report •

#1
August 22, 2018 at 03:47:56
Very doable, but will take some time to write.
Give me like an hour or too, as i do not have much time right now

props to the explanation :)

I do have two question tho.
Is it just one file, or mutiple model files?
and
does the star ( * ) in the file represent random text or is it an actual star?
I'm asking just because it is a special character that might have to be escaped to be worked with.
Telling me would be nice

i5-6600K[delid]@4.8GHz/4.3GHz@1.4v LLC=6 | 2x4GB Crucial-DDR4-2133CL15@14-14-14-28 1T 2700MHz@1.35v
MSI Armor RX 570 4GB@1340Mhz core@1.110v/1865MHz BiosModded


Reply ↓  Report •

#2
August 22, 2018 at 04:17:10
the .bat script:


@echo off&setlocal enabledelayedexpansion
set model=file.txt
set outputfile=output.txt
set triggered=0
for /f "tokens=*" %%a in ('type "%model%" ^| find /V ""') do (
set "line=%%a"
if "!line:~0,15!"=="Connection Culv" (
echo !line! - New text here >> %outputfile%
set triggered=1
) else (
if "!triggered!"=="0" (
echo !line! >> %outputfile%
)
if "!triggered!"=="1" (
echo !line! This should be new too >> %outputfile%
set triggered=0
)
)
)


results:

Connection Culv=This is Line1 - New text here
111 111 This should be new too
Conn Culvert Barrel=Culvert1
*
Connection Culv=This is Line2 - New text here
222 222 This should be new too
Conn Culvert Barrel=Culvert2
*
Connection Culv=This is Line3 - New text here
333 333 This should be new too
Conn Culvert Barrel=Culvert3
*

the values of model & outputfile should be changed to your liking

i5-6600K[delid]@4.8GHz/4.3GHz@1.4v LLC=6 | 2x4GB Crucial-DDR4-2133CL15@14-14-14-28 1T 2700MHz@1.35v
MSI Armor RX 570 4GB@1340Mhz core@1.110v/1865MHz BiosModded


Reply ↓  Report •

#3
August 22, 2018 at 06:46:35
Thank you for the reply. I provided a very simplified, striped down version of the model itself. There are thousands of lines of code and there are hundreds of these lines that I need to replace scattered throughout the model and each replacement is different, so unfortunately including the replacement text in the code will not work. Sorry if I was not clear on that in my initial post. Here is a small example of the actual model itself and replacement lines of code - there are 3 examples of the culvert line that I would need to replace in this snipit - all in bold (#1. Conn Culvert Barrel=1,Cul1,0, #2. Conn Culvert Barrel=2,Cul1,0, #3. Conn Culvert Barrel=1,Cul2,0) as well as the line following each of these (#1. 100 100, #2 115 115, #3. 50 50). Replacements are based on the unique identifier lines (in italics) that are right after the needed replacement lines (#1. Conn Culvert Barrel=1,Cul1,0, #2. Conn Culvert Barrel=2,Cul1,0, #3. Conn Culvert Barrel=1,Cul2,2).

Thanks again for any help:

MODEL SNIPIT HERE
BreakLine Name=BL1
BreakLine CellSize Min=
BreakLine CellSize Max=
BreakLine Near Repeats=1
BreakLine Polyline= 2
749229.01307448720208.606197753 749310.99413914719981.581711002
Connection=Connection1 ,749170.3458749,719393.4466371
Connection Desc=
Connection Line=4
749264.197132839719397.961390208749158.302314896719392.527851194
749148.302367149719392.560178611 749076.48011895719389.280834652
Connection Last Edited Time=Aug/17/2018 12:55:44
Conn Near Repeats=1
Connection Up Reach=
Connection Up River=
Connection Up RS=
Connection Dn Reach=
Connection Dn River=
Connection Dn RS=
Conn Routing Type= 1
Conn Use RC Family=False
Conn OverFlow Method 2D=False
Conn Weir WD=10
Conn Weir Coef=3
Conn Weir Is Ogee= 0
Conn Simple Spill Pos Coef=0.05
Conn Simple Spill Neg Coef=0.05
Conn Weir SE= 18
01500.45630.77757 1500.7940.786091500.95655.810461501.13160.817041501.216
65.823611501.27975.836771501.38685.849921501.55495.863081501.659100.86971501.775
116.03411502.304120.88151502.426135.89721502.754140.90241502.841152.95841503.119
179.7221503.689185.9493 1503.88187.93121503.923
Connection Culv=2,3,10,100.69,0.02,0.3,1,8,1,1002,1001, 1 ,Group1B , 0 ,
100 100

Conn Culvert Barrel=1,Cul1,0
Conn Culv Bottom n=0.02
Connection Culv=1,3,,100.69,0.02,0.3,1,2,3,1000.01,999.01, 1 ,Group1A , 0 ,
115 115

Conn Culvert Barrel=2,Cul1,0
Conn Culv Bottom n=0.02

Conn Outlet Rating Curve= 0 ,False,,
Connection=Connection2 ,749150.8027089,720183.502415
Connection Desc=
Connection Line=3
749212.113799506720183.551667985749148.471637979720183.975109164
749089.500952284720182.466598541
Connection Last Edited Time=Aug/17/2018 12:56:39
Conn Near Repeats=1
Connection Up Reach=
Connection Up River=
Connection Up RS=
Connection Dn Reach=
Connection Dn River=
Connection Dn RS=
Conn Routing Type= 1
Conn Use RC Family=False
Conn OverFlow Method 2D=False
Conn Weir WD=10
Conn Weir Coef=3
Conn Weir Is Ogee= 0
Conn Simple Spill Pos Coef=0.05
Conn Simple Spill Neg Coef=0.05
Conn Weir SE= 15
01505.09818.654211505.91923.654321506.17528.654431506.16133.654541505.944
58.65511505.82883.661761505.80188.66339 1505.7493.665021505.73598.666661505.694
103.66831505.722108.66991505.781113.67161505.877118.67321506.027122.6335 1506.19
Connection Culv=4,3,4,79.64,0.02,0.3,1,29,2,1505,1504.5, 1 ,Group2 , 0 ,
50 50

Conn Culvert Barrel=1,Cul2,2
749148.417384509720223.797157772749148.525891449720144.153060555
Conn Culv Bottom n=0.02

Conn Outlet Rating Curve= 0 ,False,,
LCMann Time=Dec/30/1899 00:00:00
LCMann Region Time=Dec/30/1899 00:00:00
LCMann Table=0
Chan Stop Cuts=-1

SAMPLE REPLACEMENT LINES FOR CODE
Connection Culv=1,2,3,4,5,6,7,8,9,10,11, 12 ,GroupA , 13 ,
100 85
Conn Culvert Barrel=1,Cul2,2
*
Connection Culv=14,15,16,17,18,19,20,21,22,23,24, 25 ,GroupB , 51 ,
99 105
Conn Culvert Barrel=1,Cul1,0
*
Connection Culv=5,10,15,20,25,30,35,40,45,50,55, 60 ,GroupXX , 99 ,
121 142
Conn Culvert Barrel=2,Cul1,0


Reply ↓  Report •

Related Solutions

#4
August 22, 2018 at 08:18:13
In example #1, How am i supposed to calulate these: 1,2,3,4,5,6,7,8,9,10,11, 12 ,GroupA , 13 ,
100 85
and how do these tokens relate to 1,Cul2,2?

also why are the unique identifier lines, from:

Conn Culvert Barrel=1,Cul1,0
Conn Culvert Barrel=2,Cul1,0
Conn Culvert Barrel=1,Cul2,2

to

Conn Culvert Barrel=1,Cul2,2
Conn Culvert Barrel=1,Cul1,0
Conn Culvert Barrel=2,Cul1,0

i mena they changed from 1,1,0 / 2,1,0 / 1,2,2 --> 1,2,2 / 1,1,0 / 2,1,0

do you want me to move these values around?

I'm sorry I'm just not seing the patterns, for me to work it out

Would you mind providing 1 more example output with correct values, based on your example moddel snippet

and maby explain what the values are based on in full

i5-6600K[delid]@4.8GHz/4.3GHz@1.4v LLC=6 | 2x4GB Crucial-DDR4-2133CL15@14-14-14-28 1T 2700MHz@1.35v
MSI Armor RX 570 4GB@1340Mhz core@1.110v/1865MHz BiosModded


Reply ↓  Report •

#5
August 22, 2018 at 09:38:32
I know it is weird, sorry. The unique identifier is below the lines that I need to change, and the file with the new values is not in the same order as the original model. One thought is that the 2 lines I need to change are always the 2 lines immediately preceding the unique identifier line. Thanks for your time and help.

So from the snippit I provided earlier the final results would be as shown below:

FINAL OUTPUT MODEL SNIPIT HERE
BreakLine Name=BL1
BreakLine CellSize Min=
BreakLine CellSize Max=
BreakLine Near Repeats=1
BreakLine Polyline= 2
749229.01307448720208.606197753 749310.99413914719981.581711002
Connection=Connection1 ,749170.3458749,719393.4466371
Connection Desc=
Connection Line=4
749264.197132839719397.961390208749158.302314896719392.527851194
749148.302367149719392.560178611 749076.48011895719389.280834652
Connection Last Edited Time=Aug/17/2018 12:55:44
Conn Near Repeats=1
Connection Up Reach=
Connection Up River=
Connection Up RS=
Connection Dn Reach=
Connection Dn River=
Connection Dn RS=
Conn Routing Type= 1
Conn Use RC Family=False
Conn OverFlow Method 2D=False
Conn Weir WD=10
Conn Weir Coef=3
Conn Weir Is Ogee= 0
Conn Simple Spill Pos Coef=0.05
Conn Simple Spill Neg Coef=0.05
Conn Weir SE= 18
01500.45630.77757 1500.7940.786091500.95655.810461501.13160.817041501.216
65.823611501.27975.836771501.38685.849921501.55495.863081501.659100.86971501.775
116.03411502.304120.88151502.426135.89721502.754140.90241502.841152.95841503.119
179.7221503.689185.9493 1503.88187.93121503.923
Connection Culv=14,15,16,17,18,19,20,21,22,23,24, 25 ,GroupB , 51 ,
99 105

Conn Culvert Barrel=1,Cul1,0
Conn Culv Bottom n=0.02
Connection Culv=5,10,15,20,25,30,35,40,45,50,55, 60 ,GroupXX , 99 ,
121 142

Conn Culvert Barrel=2,Cul1,0
Conn Culv Bottom n=0.02

Conn Outlet Rating Curve= 0 ,False,,
Connection=Connection2 ,749150.8027089,720183.502415
Connection Desc=
Connection Line=3
749212.113799506720183.551667985749148.471637979720183.975109164
749089.500952284720182.466598541
Connection Last Edited Time=Aug/17/2018 12:56:39
Conn Near Repeats=1
Connection Up Reach=
Connection Up River=
Connection Up RS=
Connection Dn Reach=
Connection Dn River=
Connection Dn RS=
Conn Routing Type= 1
Conn Use RC Family=False
Conn OverFlow Method 2D=False
Conn Weir WD=10
Conn Weir Coef=3
Conn Weir Is Ogee= 0
Conn Simple Spill Pos Coef=0.05
Conn Simple Spill Neg Coef=0.05
Conn Weir SE= 15
01505.09818.654211505.91923.654321506.17528.654431506.16133.654541505.944
58.65511505.82883.661761505.80188.66339 1505.7493.665021505.73598.666661505.694
103.66831505.722108.66991505.781113.67161505.877118.67321506.027122.6335 1506.19
Connection Culv=1,2,3,4,5,6,7,8,9,10,11, 12 ,GroupA , 13 ,
100 85

Conn Culvert Barrel=1,Cul2,2
749148.417384509720223.797157772749148.525891449720144.153060555
Conn Culv Bottom n=0.02

Conn Outlet Rating Curve= 0 ,False,,
LCMann Time=Dec/30/1899 00:00:00
LCMann Region Time=Dec/30/1899 00:00:00
LCMann Table=0
Chan Stop Cuts=-1


Reply ↓  Report •

#6
August 23, 2018 at 01:34:42
Because you want to change preceding lines, doing so will be a bit harder to code, since the script will be reading the file from the top downwards, but that does not mean it can't be done :).

Will be working on it today or maby tommorow

i5-6600K[delid]@4.8GHz/4.3GHz@1.4v LLC=6 | 2x4GB Crucial-DDR4-2133CL15@14-14-14-28 1T 2700MHz@1.35v
MSI Armor RX 570 4GB@1340Mhz core@1.110v/1865MHz BiosModded


Reply ↓  Report •

#7
August 23, 2018 at 04:53:40
this test.bat outputs to output.txt in the directory it is launched in.
you can change the values of inputfile & outputfile

I've tested it & the result is a .txt file containing exactly what you've posted in #5

the .bat:

@echo off&setlocal enabledelayedexpansion
set inputfile=input.txt
set outputfile=output.txt
set oldPline=
set newPline=
set line=
@echo off > %outputfile%
for /f "tokens=*" %%a in ('type "%inputfile%" ^| find /V ""') do (
if not "!oldPline!"=="" (
echo !oldPline! >> %outputfile%
)
set "oldPline=!newPline!"
set "newPline=!line!"
set "line=%%a"
if "!line:~0,19!"=="Conn Culvert Barrel" (
for /f "tokens=2-4 delims=,=" %%A in ("!line!") do (
if "%%A,%%B,%%C"=="1,Cul1,0" (
set "oldPline=Connection Culv=14,15,16,17,18,19,20,21,22,23,24, 25 ,GroupB , 51 ,"
set "newPline=99 105"
)
if "%%A,%%B,%%C"=="2,Cul1,0" (
set "oldPline=Connection Culv=5,10,15,20,25,30,35,40,45,50,55, 60 ,GroupXX , 99 ,"
set "newPline=121 142"
)
if "%%A,%%B,%%C"=="1,Cul2,2" (
set "oldPline=Connection Culv=1,2,3,4,5,6,7,8,9,10,11, 12 ,GroupA , 13 ,"
set "newPline=100 85"
)
)
)
)
echo !newPline! >> %outputfile%
echo !line! >> %outputfile%

i5-6600K[delid]@4.8GHz/4.3GHz@1.4v LLC=6 | 2x4GB Crucial-DDR4-2133CL15@14-14-14-28 1T 2700MHz@1.35v
MSI Armor RX 570 4GB@1340Mhz core@1.110v/1865MHz BiosModded

message edited by hidde663


Reply ↓  Report •

Ask Question