Bash script - How to update header of scripts in one pass - multiline search/replace

Hello.
A find command return a list of file.
For each fileReplace the content starting with the first "§" (of two) ending with last "ɸ" (of two), regardless of the content ( five lines )
by the following content (exactly) :

§2019_08_23§                      #
#                                                #
#    ¨version:41-0-2¨                      #
#                                                #
#    ɸmodif_version:5-4-3ɸ

Header example :

#!/bin/bash
#
#######################
#                                                #
#    {config_std}                            #
#                                                #
#    /sys_script/000_COMMON/Bin/some_script
#                                                #
#    INSTALL VERSION                    #
#                                                #
#    §2018_03_23§                         #
#                                                #
#    ¨version:25-0-0¨                     #
#                                                #
#    ɸmodif_version:0-0-1ɸ             #
#                                                #
########################
#
# object
#
########################################################
#
#

I know nothing in perl, awk, and few things in sed.

Note : white-space are tab or space or both and are undefined.

Any help is welcome.

Are those § and ɸ always in the same line? Is the first § at BOL, and ɸ at EOL? Try

sed -e'/^§/,/ɸ$/ {/ɸ/ rheader' -e'; d}' content

To be more clear, on any files return by the command find :
1° The start pattern to search § is generaly at line 11 but should be more or less
2° The start pattern to search § is always on a new line starting with the comment character # which is followed by one ore more space or tab
3°) The end pattern to search ɸ is always the second one on the same line. Some thing like
^#.*ɸ.*ɸ.*#.*$
4°)Between the first pattern § and the last pattern ɸ there is at least 3 line :

#    §2017_08_23§                      #
#    ¨version:11-0-2¨                  #
#    ɸmodif_version:2-2-1ɸ             #
 

But it could be more

#    §2019_01_13§                      #
#                                      #
#                                      #
#    ¨version:1-0-0¨                  #
#                                      #
#                                      #
#    ɸmodif_version:0-0-3ɸ             #
 

I am looking for something like ( the following syntax is surely bad ) :
Set start and stop address; replace every things between start and stop including start and stop by the multi-line block of text :

sed '/§.*§ /,/ɸ.*ɸ/{s/.*/§2019_08_24§                      #\
#                                      #\
#    ¨version:3-0-0¨                  #
#                                      #
#    ɸmodif_version:1-1-1ɸ/}' some_file.sh

Or if the substitution text is in a bash variables :

REPLACE_VAR="$(cat <<-EOF §2019_08_24§                      #\
#                                      #\
#    ¨version:3-0-0¨                  #
#                                      #
#    ɸmodif_version:1-1-1ɸ EOF )" 

Then :

sed '/§.*§ /,/ɸ.*ɸ/{s/.*/'"$REPLACE_VAR"'/}' some_file.sh

Any help is welcome

Did you try the proposal given (based on your non-representative sample in post #1) with your revised data, perhaps with revised search patterns?

  1. The #! /bin/bash shebang is pointless on line 11.
  2. Not mentioned in your sample.
  3. The address range used in the proposal doesn't care for the numner of lines between start and end.

No, because as far as the few I knew about sed :
/^§/ stand for "§" at beginning of line
/ɸ$/ stand for "ɸ" at end of ligne

that is not the case for my file heade

The shebang is at line 1 not 11
It is the first line of the header file

Sorry I don't understand

Of course. This is the question.

How to replace all the characters ( whichever they are ) from the first "§" (including it) up to the last (including it) with the defined block of text

§2019_08_24§                      #\
 #                                      #\
 #    ¨version:3-0-0¨                  #\
 #                                      #\
 #    ɸmodif_version:1-1-1ɸ

The number of line lines is useless.
There is a start point : the first "§"
There is an end point : the second "ɸ" ( or any "ɸ" followed by "[[:blank:]]#")

Doing that manually with a text editor :
1) copy (from somewhere)

the new text from the first "§" up to the last "ɸ".

2) Select
In the current file, select the text from the first "§" up to the last "ɸ". Don't care about the number of lines.

3) paste

over the selection paste the text previously copied.

I hope that make things clearer.

Thank you

--- Post updated at 01:02 ---

sed '/§.*§/,/ɸ.*ɸ/{d}' "$SOME_FILE"

is able to delete the selected text.

But

sed '/§.*§ /,/ɸ.*ɸ/{s/§.*§.*ɸ.*ɸ/§2019_08_24§                      # \
#                                      # \
#    ¨version:3-0-0¨                  # \
#                                      # \
#    ɸmodif_version:1-1-1ɸ/}' "$SOME_FILE"

Does not make any substitution.

Any help is welcome

Contrary to what I wrote yesterday, it doesn't quite do what I thought.
In fact it delates from the beginning of the line containing /start/ (complete line) until the end of the line containing/stop/ (complete line) .
From my sample that do :

#!/bin/bash 

# ####################### 

#                                                # 

#    {config_std}                            # 

#                                                # 

#    /sys_script/000_COMMON/Bin/some_script 

#                                                # 

#    INSTALL VERSION                    # 

#                                                # 

#                                                # 

######################## 

# 

# object 

# 

######################################################## 

# 

#

but I was extecting

#!/bin/bash 

# ####################### 

#                                                # 

#    {config_std}                            # 

#                                                # 

#    /sys_script/000_COMMON/Bin/some_script 

#                                                #
#    INSTALL VERSION                    # 

#                                                # 

#     §2018_03_23§........ 
 ..................................
 ...................................
...................................
......ɸmodif_version:0-0-1ɸ              #
#                                                #

#                                                # 
######################## 

# 

# object 

# 

######################################################## 

# 

#

The expected deleted text is in red.

The best I have found is :

sed 's/§.*§/§2019_08_25§/    ;    s/¨.*¨/¨version:34-1-9¨/    ;    s/ɸ.*ɸ/ɸmodif_version:9-7-3ɸ/' "$SOME_FILE"

But that does not convert :

#!/bin/bash 
# 
####################### 
#                                        # 
#    {config_std}                        # 
#                                        # 
#    /sys_script/000_COMMON/Bin/some_script 
#                                        # 
#    INSTALL VERSION                     # 
#                                        # 
#    §2018_03_23§                        # 
#                                        # 
#                                        # 
#    ¨version:25-0-0¨                    # 
#                                        # 
#                                        # 
#                                        # 
#                                        # 
#    ɸmodif_version:0-0-1ɸ               # 
#                                        # 
######################## 
# 
# object 
# 
######################################################## 
# 
#

to

#!/bin/bash 
# 
####################### 
#                                        #
#    {config_std}                        # 
#                                        #
#    /sys_script/000_COMMON/Bin/some_script 
#                                        #
#    INSTALL VERSION                     # 
#                                        #
#    §2019_08_25§                        # 
#                                        #
#    ¨version:34-1-9¨                    # 
#                                        #
#    ɸmodif_version:9-7-3ɸ               # 
#                                        #
######################## 
# 
# object 
# 
######################################################## 
# 
#

Which should be nice for me.

Here I used awk to replace everything except "#" on your "§" line with spaces. This is used as a template to insert the required comments:

awk -v D=2019_08_25 -v V=34-1-9 -v M=9-7-3 '
function com(str) {
   print substr($0, 0, pos - 1) str substr($0, pos + length(str))
}
/§/ {
   pos=index($0, "§")
   gsub(/[^# \t]/, " ")
   com("§" D "§")
   com("")
   com("¨version:" V "¨")
   com("")
   com("ɸmodif_version:" M "ɸ")
   skip=1
}
/ɸ/ && skip==1 { skip = 2 ; next }
skip == 1 {next }
1' "$SOME_FILE"

This helps the formatting to match:

#!/bin/bash 
# 
####################### 
#                                        # 
#    {config_std}                        # 
#                                        # 
#    /sys_script/000_COMMON/Bin/some_script 
#                                        # 
#    INSTALL VERSION                     # 
#                                        # 
#    §2019_08_25§                        #  
#                                        #  
#    ¨version:34-1-9¨                    #  
#                                        #  
#    ɸmodif_version:9-7-3ɸ               #  
#                                        # 
######################## 
# 
# object 
# 
######################################################## 
# 
#
1 Like

Thank you very much