Python: Join consecutive lines if separated by backslash and remove backslash also
Question:
I have got a file containing shell commands. Each command may be split across multiple lines (using backslash at end):
e.g.
cmd1 -opt1
-opt2 val2
-opt3 val3 val4
I want to join consecutive lines if separated by backslash at end. i also want to remove backslash after joining.
The problem is similar to:
Input:
[‘abc’, ‘def \’, ‘ghi \’, ‘jkl’ , ‘yyy \’, ‘zzz’]
output:
[‘abc’, ‘def ghi jkl’, ‘yyy zzz’]
is looping through the list only solution ?
with open("cmd", "r") as fp:
cmd = ""
cont = False
list = []
for line in fp:
line = line.rstrip("n")
if line.endswith('\'):
line = line[:-1]
if cont:
cmd = cmd + line
continue
if cmd:
list.append(cmd)
cmd = line
cont = True
else:
if cont:
cmd = cmd + line
if cmd:
list.append(cmd)
cmd = ""
continue
cont = False
print(list)
Answers:
is looping through the list only solution ?
You will have to assess each line for a concatenation indicator and append the next line. Yes, you’ll have to loop through.
Here’s a function to do it using a generator so the whole input doesn’t need to be in memory.
>>> sample = ['abc', 'def \', 'ghi \', 'jkl' , 'yyy \', 'zzz']
>>>
>>> def join_lines(sequence):
... i = iter(sequence)
... buff = ''
... try:
... while True:
... line = i.next()
... if line.endswith('\'):
... line = line[:-1]
... buff += line
... else:
... if buff:
... buff += line
... yield buff
... buff = ''
... else:
... yield line
... except StopIteration:
... if buff:
... yield buff
...
>>> print sample
['abc', 'def \', 'ghi \', 'jkl', 'yyy \', 'zzz']
>>> print list(join_lines(sample))
['abc', 'def ghi jkl', 'yyy zzz']
cmd = ['abc', 'def \', 'ghi \', 'jkl' , 'yyy \', 'zzz']
res = "n".join(cmd).replace("\\n", "").splitlines()
print(res)
=> ['abc', 'def ghi jkl', 'yyy zzz']
This can be way to join lines and iterate over such a file:
with open("cmd", "r") as fp:
data = fp.read()
lines = data.replace("\n", "").splitlines()
lines = [ x + "n" for x in lines ]
for line in lines:
print(line)
I have got a file containing shell commands. Each command may be split across multiple lines (using backslash at end):
e.g.
cmd1 -opt1
-opt2 val2
-opt3 val3 val4
I want to join consecutive lines if separated by backslash at end. i also want to remove backslash after joining.
The problem is similar to:
Input:
[‘abc’, ‘def \’, ‘ghi \’, ‘jkl’ , ‘yyy \’, ‘zzz’]
output:
[‘abc’, ‘def ghi jkl’, ‘yyy zzz’]
is looping through the list only solution ?
with open("cmd", "r") as fp:
cmd = ""
cont = False
list = []
for line in fp:
line = line.rstrip("n")
if line.endswith('\'):
line = line[:-1]
if cont:
cmd = cmd + line
continue
if cmd:
list.append(cmd)
cmd = line
cont = True
else:
if cont:
cmd = cmd + line
if cmd:
list.append(cmd)
cmd = ""
continue
cont = False
print(list)
is looping through the list only solution ?
You will have to assess each line for a concatenation indicator and append the next line. Yes, you’ll have to loop through.
Here’s a function to do it using a generator so the whole input doesn’t need to be in memory.
>>> sample = ['abc', 'def \', 'ghi \', 'jkl' , 'yyy \', 'zzz']
>>>
>>> def join_lines(sequence):
... i = iter(sequence)
... buff = ''
... try:
... while True:
... line = i.next()
... if line.endswith('\'):
... line = line[:-1]
... buff += line
... else:
... if buff:
... buff += line
... yield buff
... buff = ''
... else:
... yield line
... except StopIteration:
... if buff:
... yield buff
...
>>> print sample
['abc', 'def \', 'ghi \', 'jkl', 'yyy \', 'zzz']
>>> print list(join_lines(sample))
['abc', 'def ghi jkl', 'yyy zzz']
cmd = ['abc', 'def \', 'ghi \', 'jkl' , 'yyy \', 'zzz']
res = "n".join(cmd).replace("\\n", "").splitlines()
print(res)
=> ['abc', 'def ghi jkl', 'yyy zzz']
This can be way to join lines and iterate over such a file:
with open("cmd", "r") as fp:
data = fp.read()
lines = data.replace("\n", "").splitlines()
lines = [ x + "n" for x in lines ]
for line in lines:
print(line)