86 lines
2.7 KiB
Python
86 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
from pathlib import Path
|
|
import re
|
|
|
|
inp = Path(r"d:\TJWaterServer\epanet\szhskeleton-patternfixed-ascii.inp")
|
|
out = Path(r"d:\TJWaterServer\epanet\szhskeleton-patternfixed-ascii-fixed2.inp")
|
|
mapout = Path(r"d:\TJWaterServer\epanet\szhskeleton-patternfixed-ascii-fixed2.mapping.txt")
|
|
|
|
text = inp.read_text(encoding='utf-8')
|
|
lines = text.splitlines()
|
|
|
|
# find [VALVES] start and end
|
|
start = None
|
|
for i,l in enumerate(lines):
|
|
if l.strip().upper() == '[VALVES]':
|
|
start = i
|
|
break
|
|
if start is None:
|
|
print('No [VALVES] section found')
|
|
raise SystemExit(1)
|
|
end = len(lines)
|
|
for j in range(start+1, len(lines)):
|
|
if re.match(r"^\s*\[.+\]", lines[j]):
|
|
end = j
|
|
break
|
|
|
|
# collect valve lines with their absolute numbers
|
|
valve_entries = [] # (absolute_line_index, token, line)
|
|
for idx in range(start+1, end):
|
|
l = lines[idx]
|
|
if not l.strip() or l.strip().startswith(';'):
|
|
continue
|
|
tok = l.split()[0]
|
|
valve_entries.append((idx, tok, l))
|
|
|
|
from collections import defaultdict
|
|
positions = defaultdict(list)
|
|
for ln, tok, l in valve_entries:
|
|
positions[tok].append(ln)
|
|
|
|
# find duplicates
|
|
dups = {tok:lns for tok,lns in positions.items() if len(lns)>1}
|
|
print('Found', sum(1 for _ in valve_entries), 'valve entries; duplicates:', len(dups))
|
|
|
|
replacements = [] # (line_index, old, new)
|
|
counter = 1
|
|
for tok, lns in dups.items():
|
|
# skip first occurrence, rename others
|
|
for occ_index, ln in enumerate(lns):
|
|
if occ_index == 0:
|
|
continue
|
|
# produce new name: prefix V if starts with digit
|
|
if re.fullmatch(r"\d+", tok) or re.match(r"^\d", tok):
|
|
base = 'V' + tok
|
|
else:
|
|
base = tok
|
|
new = f'{base}_{occ_index}'
|
|
# ensure uniqueness globally
|
|
while any(rn == new for _,_,rn in replacements) or any(new == t for t in positions.keys()):
|
|
counter += 1
|
|
new = f'{base}_{occ_index}_{counter}'
|
|
replacements.append((ln, tok, new))
|
|
|
|
# Apply replacements on the given absolute lines
|
|
for ln, old, new in replacements:
|
|
line = lines[ln]
|
|
# replace only first token occurrence
|
|
parts = line.split()
|
|
if parts:
|
|
# find start of token in line (preserve spacing)
|
|
m = re.search(re.escape(parts[0]), line)
|
|
if m:
|
|
startpos = m.start()
|
|
endpos = m.end()
|
|
newline = line[:startpos] + new + line[endpos:]
|
|
lines[ln] = newline
|
|
|
|
# write new file
|
|
out.write_text('\n'.join(lines) + '\n', encoding='utf-8')
|
|
# write mapping
|
|
with mapout.open('w', encoding='utf-8') as f:
|
|
for ln, old, new in replacements:
|
|
f.write(f'line {ln+1}: {old} -> {new}\n')
|
|
|
|
print('Wrote', out, 'with', len(replacements), 'replacements; mapping at', mapout)
|