Last active
May 11, 2018 15:50
-
-
Save hughdbrown/6042b01c9561d7fa2351aa9d3a5501a5 to your computer and use it in GitHub Desktop.
Apply a set of changes in grep -n format to a file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Given a set of file names, line numbers, and lines of text in `grep -n` format, | |
update the file with altered text. | |
Suppose you have added a bunch of lines of code to your code base that have double | |
quotes when it is your company practice to use single quotes. When you are cleaning | |
up your code for a pull-request, you find all the changes with double quotes, | |
drop extraneous lines, change all the double quotes to single quotes in the | |
grep output, and use this python code to apply changes to your files. | |
Sort of like this: | |
``` | |
$ grep -n '"' $(git diff --name-only HEAD~2 | grep -v '.csv') > a | |
$ sed -i -e '/"""/d' a | |
$ sed -i "s/\"/'/g" a | |
$ python apply_grep_script.py a | |
``` | |
""" | |
from itertools import groupby | |
import re | |
from operator import itemgetter | |
line_re = re.compile(r""" | |
^(?P<filename>[^:]+) | |
: | |
(?P<lineno>[^:]+) | |
: | |
(?P<rest>.*)$ | |
""", re.VERBOSE) | |
def main(script): | |
with open(script) as handle: | |
lines = [line.rstrip() for line in handle] | |
matches = (line_re.match(line) for line in lines) | |
groupdict_iter = ( | |
m.groupdict() | |
for m in matches | |
) | |
actions = [ | |
(g['filename'], int(g['lineno']) - 1, g['rest']) | |
for g in groupdict_iter | |
] | |
for k, g in groupby(actions, itemgetter(0)): | |
# Read file | |
with open(k) as handle: | |
lines = [line.rstrip() for line in handle] | |
print("Processing {0}: {1} lines".format(k, len(lines))) | |
# Perform replacements | |
for _, lineno, replacement in g: | |
lines[lineno] = replacement | |
# Write file | |
with open(k, "w") as handle: | |
handle.write("\n".join(lines) + "\n") | |
if __name__ == '__main__': | |
import sys | |
for script in sys.argv[1:]: | |
main(script) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment