Skip to content

Instantly share code, notes, and snippets.

@Xowap
Last active January 25, 2016 18:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xowap/62a5e12f36de80cffdc9 to your computer and use it in GitHub Desktop.
Save Xowap/62a5e12f36de80cffdc9 to your computer and use it in GitHub Desktop.
Replace SSL certificates in all files and keep indentation
#!/usr/bin/env python3
# vim: fileencoding=utf-8 tw=100 expandtab ts=4 sw=4 :
#
# ssh_replacer
# (c) 2015 ActivKonnect
from sys import argv, exit, stderr
from re import compile
from os import walk, path
import json
WHITESPACE_RE = compile(r'^([ \t]*)([^\r\n]*)([\r\n]*)')
class IndentedString(str):
def __new__(cls, obj, *args, **kwargs):
real_str = str(obj)
m = WHITESPACE_RE.match(real_str)
clean_str = super(IndentedString, cls).__new__(cls, m.group(2), *args, **kwargs)
clean_str.real_str = real_str
clean_str.indent = m.group(1)
clean_str.eol = m.group(3)
return clean_str
def read_file(file_name):
with open(file_name) as f:
return [IndentedString(x) for x in f.readlines()]
def list_files(dir_name):
if path.isdir(dir_name):
for root, dirs, files in walk(dir_name):
for file_name in sorted(files):
yield path.join(root, file_name)
else:
yield dir_name
def find(haystack, needle):
progress = 0
for i, line in enumerate(haystack):
if line == needle[progress]:
progress += 1
else:
progress = 0
if progress == len(needle):
return i - progress + 1
def replace(src, old, new):
pos = find(src, old)
if pos is not None:
indent = src[pos].indent
eol = src[pos].eol
last_eol = src[pos + len(old) - 1].eol
formatted_new = [indent + x + (eol if i != len(new) - 1 else last_eol)
for i, x in enumerate(new)]
return True, src[0:pos] + formatted_new + src[pos + len(old):]
else:
return False, src
def get_real_str(string):
return getattr(string, 'real_str', string)
def main(target_dir, old, new):
old_f = read_file(old)
new_f = read_file(new)
for file_name in list_files(target_dir):
try:
file_content = read_file(file_name)
replaced, new_content = replace(file_content, old_f, new_f)
if replaced:
print('### {}'.format(file_name))
with open(file_name, 'w') as f:
f.write(''.join(get_real_str(x) for x in new_content))
except UnicodeDecodeError:
pass
if __name__ == '__main__':
if len(argv) != 4:
print('Usage: python3 {} <target_dir> <old> <new>'.format(argv[0]), file=stderr)
exit(1)
main(*argv[1:])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment