bashunixed

Move contents of one section above another section in a configuration file


I have a requirement to move [mysqld] section in a mysql configuration file above another section named #SAFE# in a mysql configuration file and after the section is moved there should be space between the sections,Please find the below code and requirement:

code used:

#!/bin/bash
for server in `cat /home/servers.txt'`
username=$1
password=$2
do
sshpass-p $PWD ssh -o stricthostchecking=no $USERNAME@$server "ed -s /home/my.cnf <<'EOF'
/^\[mysqld\]$/;/^\[.*/ -1m$
?\[mysqld\]?i

.
w
EOF"
done

Actual my.cnf:

   [client]
   a=2
   b=7
   
   [mysql]
    d=6
    e=7
 
   [mysqld]
    
    disable-log-bin = 1
    
    skip-name-resolve = 1
    performance-schema = 0
    local-infile = 0
    mysqlx = 0
    open_files_limit = 200000
    max_allowed_packet = 256M
    sql_mode="NO_ENGINE_SUBSTITUTION"

    #the below are password related of [mysqld]
     validate password=1
    
    innodb_dedicated_server = 1
    innodb_buffer_pool_instances = 48
    
    [myisamck]
    a=3
    b=4
    
    [sst]
    d=3
    c=4
    
    # SAFE #
    d=0
    f=0
    

Requirement:

The [mysqld] section and its sections should be pasted above # SAFE #( section in very few cases section is given as ##SAFE## or #SAFE# or # SAFE # in few of the my.cnf files),Please support.

Expected output:

  [client]
   a=2
   b=7
   
   [mysql]
    d=6
    e=7
    
    [myisamck]
    a=3
    b=4
    
    [sst]
    d=3
    c=4
    
   [mysqld]
    
    disable-log-bin = 1
    
    skip-name-resolve = 1
    performance-schema = 0
    local-infile = 0
    mysqlx = 0
    open_files_limit = 200000
    max_allowed_packet = 256M
    sql_mode="NO_ENGINE_SUBSTITUTION"
    
    #the below are password related of [mysqld]
     validate password=1

    innodb_dedicated_server = 1
    innodb_buffer_pool_instances = 48
    
    # SAFE #
    d=0
    f=0

Solution

  • I don't use sshpass but plain ol ssh with key, something like:

    #!/usr/bin/env bash
    
    servers=(
      server1
      server2
      server3
      ...
    )
    
    for server in "${servers[@]}"; do
      ssh -t "jetchisel@$server" 'ed -s ~/my.cnf <<EOF
      /#*[[:space:]]*SAFE[[:space:]]*#*/kx
      /^\[mysqld\]$/;/^\[.*/-1m'\''x-1
      ,p
      Q
    EOF'
    done
    

    To add the content of /home/servers.txt to an array, one way is to use mapfile aka readarray which is a bash4+ feature.

    mapfile -t servers < /home/servers.txt