使用Sed替换Python文件中的双括号为单括号的技术问询
Got it, let's break down how to solve this problem—replacing those unnecessary double parentheses (like print((...))) with single ones, even when the content spans multiple lines.
First: Single-Line Cases
For straightforward single-line instances (like print((something)) or print(('hello'))), a simple Sed command will do the trick. We'll use extended regular expressions to target consecutive opening/closing parentheses without messing up legitimate nested calls (like foo(bar(baz))):
sed -E 's/(\()\(/\1/g; s/\)(\))/\1/g' your_python_script.py
How this works:
s/(\()\(/\1/g: Captures the first opening parenthesis, then replaces two consecutive((with just one(.s/(\))\)/\1/g: Captures the last closing parenthesis, replacing two consecutive))with just one).
Handling Multi-Line Strings
If you have print statements split across lines (like the string concatenation example you mentioned), Sed's default line-by-line processing won't catch the closing )) that's on a different line. We need to tell Sed to read multiple lines into its "pattern space" first:
sed -E -N ' :multi_line_loop N # Apply the same parenthesis replacement as before s/(\()\(/\1/g; s/\)(\))/\1/g # If we still see a closing parenthesis after a newline, keep looping to read more lines /\n.*\))/b multi_line_loop # Print the first line of the pattern space and remove it to process the rest P D ' your_python_script.py
Going the Extra Mile: Remove All Levels of Extra Parentheses
If you have cases with triple (or more) parentheses (like print(((deep_nested)))), you can add a loop to keep replacing until no more double parentheses exist:
sed -E ':cleanup_loop; s/(\()\(/\1/g; s/\)(\))/\1/g; t cleanup_loop' your_python_script.py
The t cleanup_loop command tells Sed to jump back to the cleanup_loop label only if a replacement was made—so it'll keep stripping extra parentheses until none are left.
Safety First: Backup Your File
Always make a backup before modifying files in place! Use the -i flag with a backup suffix to let Sed handle this:
# Creates a backup file named your_python_script.py.bak, then modifies the original sed -i.bak -E ':cleanup_loop; s/(\()\(/\1/g; s/\)(\))/\1/g; t cleanup_loop' your_python_script.py
Test It Out
Let's say you have this code:
print((something)) print(('>> # some text and ' + 'some more text')) print(('>> # line 1 ' + 'line 2')) foo(((bar)))
After running the final command, it'll become:
print(something) print('>> # some text and ' + 'some more text') print('>> # line 1 ' + 'line 2') foo(bar)
内容的提问来源于stack exchange,提问作者Sam

