1

I have a python file, which has lots of double parentheses like this, which i would like to replace with single parenthesis. Sometimes the print goes on for 2 lines or more.

print(('>>   # some text some text some text and ' 
+ 'some more text'))
print(('>>   # some text some text some text and ' 
+ 'some more text'))

print(('>>   # some text some text some text and ' 
+ 'some more text'))


print(('>>   # some text some text some text and ' 
+ 'some more text'))


print((something))
print((something))

print((something))

print((something))


print((something))



print((something))

I have tried a lot different ways to approach this. I think the easiest would be with sed. I have something like this:

grep -rl 'print((' test.txt | xargs sed -i "N;s/print((\(.*\)))/print(\1)/g"

The output looks like this:

print('>>   # some text some text some text and ' 
+ 'some more text')
print('>>   # some text some text some text and ' 
+ 'some more text')

print(('>>   # some text some text some text and ' 
+ 'some more text'))


print(('>>   # some text some text some text and ' 
+ 'some more text'))


print(something)
print(something)

print(something)

print(something)


print(something)



print(something)

Now with some lines it works but with some it doesn't, i think it is because of the N; but i need this in case it is multiple lines long..

What could i do to improve this pattern?

Sam
  • 13
  • 5
  • you could use `sed -z 's/print(\(([^)]*)\))/print\1/g'` for small enough input files.. but this would fail if content inside the parenthesis includes a `)` and assumes that input file doesn't contain ASCII NUL character... – Sundeep May 08 '18 at 08:57
  • also, to avoid issues due to input file names, use `grep -rlZ 'regex' | xargs -0 sed ...` – Sundeep May 08 '18 at 08:58
  • `perl -0777 -pe 's/print\(\((.*?)\)\)/print($1)/sg'` might do better than `sed` version as `))` being part of content inside parenthesis might be rarer than just `)` – Sundeep May 08 '18 at 09:04
  • @Sundeep sometimes it's like this: `print(( something, somethingelse() ))` – Sam May 08 '18 at 09:08
  • @Sundeep and i have to this for a directory, so `test.txt` would be replaced with `./` – Sam May 08 '18 at 09:10
  • yeah, I mentioned those points while suggesting the solutions.. try the perl one.. – Sundeep May 08 '18 at 09:12
  • again, I mentioned that in the comment.. you should improve your sample data with these cases.. – Sundeep May 08 '18 at 09:26
  • @Sundeep Why did you delete your answer? i wanted to mark it : ) – Sam May 08 '18 at 09:33
  • well, you mentioned it didn't work for all cases.. so I deleted it – Sundeep May 08 '18 at 09:41
  • @Sundeep actually it worked on all my files maybe there are exceptions but for me it worked so i would like to accept it – Sam May 08 '18 at 11:36
  • ok, I've undeleted it now :) – Sundeep May 08 '18 at 11:48

1 Answers1

0

to avoid issues due to input file names, use grep -rlZ 'regex' | xargs -0 <command ...>


if content within parenthesis doesn't have )), then you can use this

grep -rlZ 'print((' | xargs -0 perl -i -0777 -pe 's/print\(\((.*?)\)\)/print($1)/sg'
  • -0777 to slurp entire file content as a single string, so this solution not fit for large files that cannot fit memory requirements
  • .*? is non-greedy matching
  • s modifier allows to match \n as well for .

When using -i option, you can specify a backup suffix (ex: -i.bkp) or prefix (ex: -i'bkp.*') or even a backup directory (ex: -i'bkp_dir/*') - these help in preserving the original copy for further use

Sundeep
  • 23,246
  • 2
  • 28
  • 103