Description
  • File1 contains exactly one section while File2 contains several sections.
  • Each section begins with a line of the form [section_name].
  • Sections may be separated by none, one or more empty lines.
  • We want to substitute the section specified in File1 for the same section in File2.
  • File2 must start with a line declaring the beginning of some section.
Raw Input
File1 contains the updated section.
[section_2]
 setting 2-1-NEW
 setting 2-2-NEW
 setting 2-3-NEW
Raw Input Desired Output
File2 is the original file.
[section_1]
 setting 1-1
 setting 1-2
 setting 1-3
[section_2] setting 2-1-OLD setting 2-2-OLD setting 2-3-OLD setting 2-4-OLD
[section_3] setting 3-1 setting 3-2
[section_4] setting 4-1 setting 4-2 setting 4-3
[section_1]
 setting 1-1
 setting 1-2
 setting 1-3
[section_2] setting 2-1-NEW setting 2-2-NEW setting 2-3-NEW
[section_3] setting 3-1 setting 3-2
[section_4] setting 4-1 setting 4-2 setting 4-3
Script and Comments
Script1
[ 1] 1h
[ 2] 1d
[ 3] /^\[/!{
[ 4] H
[ 5] d
[ 6] }
[ 7] G
[ 8] s/^([^\n]*\n[^\n]*).*/\1/
[ 9] :0
[10] /^(\[[^]]*\])\n\1$/!{
[11] P
[12] $d
[13] N
[14] s/^.*\n(.*)\n(.*)/\2\n\1/
[15] b 0
[16] }
[17] s/\n.*//
[18] :1
[19] /\n(\[|$)/!{
[20] $!N
[21] $!b 1
[22] }
[23] /\n\[/!s/^.*//
[24] s/^.*\n//
[25] x
[26] G
[27] s/\n$//
[28] :2
[29] n
[30] b 2
Comments
  1. The `-r' option of GNU sed must be used to interpret REs as EREs.
  2. The Pattern and the Hold Space is abbreviated to PS and HS, respectively.
  3. When invoking this script, we feed to sed the updated file, then the original file, for example,
    sed -r -f script_name file1 file2.
  4. This script is divided into to three parts:
    • Steps [1] thru [6] copy the first file to the HS where Steps [3] thru [6] constitute an implicit loop which will copies lines to HS until the first line of the second (original) file is read.
    • When processing the original file, to determine whether the section to be updated is reached, we have to keep the name of the updated section in PS. After Step [8], PS contains the first line of the original file. followed by a line containing only the section name, separated by a newline.
    • Steps [9] thru [30] apply the update to the original file.
  5. Steps [9] thru [16] constitute a loop which prints all lines before the section to be updated. During this loop, the name of the section to be updated is kept in PS, separated from the line being processed by a newline.
  6. Once the section to be updated is found, the kept section name is no longer needed, we use Step [17] to remove it from PS.
  7. The loop consisting of Steps [18] thru [22] continues till all lines of the section to be updated and the first line of the next section are read to PS or the end of the file is reached.
  8. After Step [27], the specified section is updated.
  9. Steps [28] thru [30] read and print the remaining lines of the original file.