#!/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)