Issue
File Content (Sample input):
cat -n file.py | grep -i -C3 "# Create a zProv customer as well"
1046 request.data['cn_cisco_origin'] = corp_nw.cn_cisco_origin
1047 request.data['o_user'] = kv['o_user']
1048
1049 # Create a zProv customer as well
1050 if is_production:
1051 if isolated_cloud:
1052 try:
--
2774 request.data['o_shared_vmanage_vbond'] = True
2775 request.data['o_user'] = kv['o_user']
2776
2777 # Create a zProv customer as well
2778 if is_production:
2779 if isolated_cloud:
2780 try:
What I want (Expected Output) :
I want to replace if is_production:
with if is_staging:
after matching the pattern # Create a zProv customer as well
1st replaced sentence should begin with 14 spaces if is_staging:
2nd replaced sentence should begin with 18 spaces if is_staging:
What I tried:
sed -i '/# Create a zProv customer as well/!b;n;c\ if is_staging:' file.py
It works fine for the 1st replacement. But it gives python indentation issue for the second replacement because the second occurence should begin with 18 spaces.
So I have to write sed command twice. The first command will be for 1st occurence with 14 spaces. The second command will be for 2nd occurence with 18 spaces.
I also tried the followings but it did not work:
sed -i '0,/# Create a zProv customer as well/{n;s/.*/\ if is_staging:/}' file.py
sed -i '1,/# Create a zProv customer as well/{n;s/.*/\ if is_staging:/}' file.py
sed -i '1s/# Create a zProv customer as well/{n;s/.*/\ if is_staging:/}' file.py
Solution
I think what you're saying boils down to that you want to match the indentation of the line following each # Create a zProv customer as well
comment to the indentation of the comment itself. And if so, then that's a more helpful way to characterize the issue than in terms of first / second / etc. matches to a pattern. This is one way you could achieve that with a single sed
command:
sed -i \
-e '/^\s*# Create a zProv customer as well/ { p; N; s/#.*/if is_staging:/; }' \
file.py
You will mostly recognize the pattern /^\s*# Create a zProv customer as well/
from your own attempts. Here I additionally ensure that the comment is preceded on its line only by whitespace, which is consistent with the example input presented, and which is important because that's the indentation that we will be reproducing.
Wherever that pattern is matched, sed
will do the following:
p
- print the contents of the pattern space (that is, the comment line).N
- append a newline and the next line of input to the pattern space. This is to consume the next line, which we want to replace in whole, without losing track of the indentation level.s/#.*/if is_staging:/
- substitute everything from the first#
to the end of the line with the wanted replacement text less any indentation. The indentation is carried over from the comment because the substitution starts at the#
.
Answered By - John Bollinger Answer Checked By - Cary Denson (WPSolving Admin)