How to do multiline search and replace with a script?
-
21-08-2019 - |
Question
I'm trying to replace every multiline import inside a Python source file.. So, the source goes like
from XXX import (
AAA,
BBB,
)
from YYY import (
CCC,
DDD,
EEE,
...
)
...other instructions...
and I'd like to get something like
from XXX import AAA, BBB
from YYY import CCC, DDD, EEE, ...
...other instructions...
I tried to use sed but it looks like it doesn't support non-greedy matching of the closing parenthesis, so it "eats" the second import.. :(
Any hint? Is this impossible with sed? Should I try with another tool?
Solution
Ummm... what's wrong with Python?
lineIter= iter(aFile)
for aLine in lineIter:
if aLine.startswith("import"):
if aLine.endswith("("):
for aModule in lineIter:
if aModule.endwith(")"):
break
print "import", aModule.strip()
else:
print aLine.stri()
else:
print aLine.strip()
OTHER TIPS
This might work for you:
sed '/^from/,/^)/{H;//{x;/)/{s/[\n()]//g;s/ */ /g;s/,$//;p;x}};d}' source
from XXX import AAA, BBB
from YYY import CCC, DDD, EEE, ...
...other instructions...
For posterity, here is a somewhat polished version of S.Lott's script (I'd have posted it as a comment, but it's too long ^^; ).. This version preserves indentation and produces a result closer to my example.
lineIter=iter(aFile) for aLine in lineIter: s = aLine.strip() if s.startswith("from ") and s.endswith("("): complete = s[:-1] for aModule in lineIter: m = aModule.strip() if m.endswith(")"): break complete += m.strip() print complete else: print aLine,
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow