Home > Net >  Replace text in a file through bash script
Replace text in a file through bash script

Time:04-21

Firstly, I can replace text in a text file using bash, the problem I have is that I have two pieces of text that need replacing but they are named the same but will require different information. So, to replace one piece of text is pretty simple, I just used (from users input):

clear
echo "Configuration of Radman properties file starting:"
read -p "Please enter the password utilised for radman in mysql configuration:" <password>
read -p "Please enter the password utilised for radius in mysql configuration:" <password>
VAR1="database.radman.datasource.password=<password>"
VAR2="database.radman.datasource.password=$<password>"
VAR3="database.radius.datasource.password=<password>"
VAR4="database.radius.datasource.password=$password>"
VAR5="/etc/radman/radman.properties"

sed -i.bak "s/${VAR1}/${VAR2}/g" ${VAR5}
sed -i.bak1 "s/${VAR3}/${VAR4}/g" ${VAR5}

But here is the issue I have with the second file (two databases):

sql raddb1 {
        dialect = "mysql"
        driver = "rlm_sql_${dialect}"
        #mysql {
        #        tls {
        #                ca_file = "/etc/ssl/certs/my_ca.crt"
        #                ca_path = "/etc/ssl/certs/"
        #                certificate_file = "/etc/ssl/certs/private/client.crt"
        #                private_key_file = "/etc/ssl/certs/private/client.key"
        #                cipher = "DHE-RSA-AES256-SHA:AES128-SHA"
        #                tls_required = yes
        #                tls_check_cert = no
        #                tls_check_cert_cn = no
        #        }
        #        warnings = auto
        #}
        server = "server1"
        port = 3306
        login = "radius"
        password = "<password>"

I need to change the "Server = " section and the "password = " section. This by itself is no problem. But there is a second database shown below:

sql raddb2 {
        dialect = "mysql"
        driver = "rlm_sql_${dialect}"
        #mysql {
        #        tls {
        #                ca_file = "/etc/ssl/certs/my_ca.crt"
        #                ca_path = "/etc/ssl/certs/"
        #                certificate_file = "/etc/ssl/certs/private/client.crt"
        #                private_key_file = "/etc/ssl/certs/private/client.key"
        #                cipher = "DHE-RSA-AES256-SHA:AES128-SHA"
        #                tls_required = yes
        #                tls_check_cert = no
        #                tls_check_cert_cn = no
        #        }
        #        warnings = auto
        #}
        server = "server2"
        port = 3306
        login = "radius"
        password = "<password>"

That has the same pattern. So if the user inputs the corect server name and password for raddb1 it will change it (as requried). But when they input the second set of variables, the pattern will be the same for raddb2. How can I change to the correct user input values for the same pattern in a single file? (This will only be the password as the server = is a different pattern for the two databases)

CodePudding user response:

The examples you've shown are a little unclear but assuming the two separate configurations for raddb1 and raddb2 are in the same file you can use range specifiers with sed. You can specify a range in many ways. Please refer to the Addresses section of the sed manpage. And this stack post.

For your specific example something like this may work.

    radpass='1@3*773@11!*'
    sed "/sql raddb1/,/password = \"radpass\"/ s|password = \"radpass\"|password = \"$radpass\"|" input_file

The stack post linked above has a detailed explanation of the use of addresses with sed but basically the above command says to start looking for substitute matches after we match the first address /sql raddb1/ then stop looking after we match the second address /password = \"radpass\"/, which in this example is the same pattern in the substitute command. You can change the first address to match the next configuration block and so on.

CodePudding user response:

Bingo. Thanks BryanK. It is now working in two blocks of code as you suggested. here is the final result that worked perfectly:

clear
echo "configuration of <file> commencing. Please answer the questions that follow for correct detailed input:"
read -p "Please enter the primary server name (listed in /etc/hosts) for database1: " primary
read -p "Please enter the radius password utilised for accessing database1: " password
filename="/etc/raddb/mods-enabled/<filename>"
VAR1="test1"
VAR2="$primary"
VAR3="radpass"
VAR4="$password"
sed -i.bak4 "s/${VAR1}/${VAR2}/g" $filename
sed -i.bak5 "/sql raddb1/,/password = \"radpass\"/ s|password = \"radpass\"|password = \"$VAR4\"|" $filename

clear
echo "configuration of <file> continuing. Please answer the questions that follow for correct detailed input:"
read -p "Please enter the secondary server name (listed in /etc/hosts) for database2: " secondary
read -p "Please enter the radius password utilised for accessing database2: " password1
filename="/etc/raddb/mods-enabled/<filename>"
VAR5="test2"
VAR6="$secondary"
VAR7="radpass"
VAR8="$password1"
sed -i.bak "s/${VAR5}/${VAR6}/g" $filename
sed -i.bak5 "/sql raddb2/,/password = \"radpass\"/ s|password = \"radpass\"|password = \"$VAR8\"|" $filename

I think with your solution, I probably do not need VAR3 and VAR7, but it works a treat. Thank you.

  • Related