Dhiraj
Dhiraj

Reputation: 497

Need to replace a specific part of line from a file using shell script

I'm trying to replace the path part of below line from postgresql.conf using shell script:

data_directory = '/var/lib/postgresql/10/main'      # use data in another directory

I first checked if I'm able to locate the line first using below script, but it did not find the line:

#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
        if [[ "$line" = "data_directory = '/var/lib/postgresql/10/main'         # use data in another directory" ]]

I know there is better way to replace this line using sed, but I need to know if its doable by reading the file from start to end and then replace the desired part of the line, if found. If not, replacing the entire line with only the path part changed will do it too. Thanks!

Upvotes: 2

Views: 330

Answers (3)

Paul Hodges
Paul Hodges

Reputation: 15246

Another approach using case - *'s allow non-exact spacing around the equals and before any comment, but introduce the small possibility of false matches. I think with the rest of the specific info on the line it's small enough that it isn't a problem.

$: cat postgresql.conf
some stuff
data_directory = '/var/lib/postgresql/10/main'         # use data in another directory
some other stuff.

$: path=/new/path/to/
$: while IFS='' read -r line || [[ -n "$line" ]]
>  do case "$line" in
>     data_directory*=*'/var/lib/postgresql/10/main'*) 
>        echo "${line//\/*\//$path}";;
>     *) echo "$line";;
>     esac
>  done < postgresql.conf >/tmp/checkme
some stuff
data_directory = '/new/path/to/main'         # use data in another directory
some other stuff.

If it's good, then

mv /tmp/checkme postgresql.conf

You could test it a few times, and then just make it automatic, but unless it's an ongoing automation that you're building I'd check it personally.

Upvotes: 2

Kubator
Kubator

Reputation: 1383

Plain bash solution:

path="/newpath"
while IFS= read -r -d $'\n'; do
  if [[ "${REPLY}" == "data_directory = '/var/lib/postgresql/10/main'      # use data in another directory" ]]
  then echo "${REPLY/\'*\'/'${path}'}"
  else echo "${REPLY}"
  fi
done < postgresql.conf > new.conf

mv new.conf postgresql.conf

Test:

$ cat postgresql.conf
# This is a comment
log_connections = yes
log_destination = 'syslog'
search_path = '"$user", public'
shared_buffers = 128MB
data_directory = '/var/lib/postgresql/10/main'      # use data in another directory
# This is a comment

$ path="/newpath"
$ while IFS= read -r -d $'\n'; do
>   if [[ "${REPLY}" == "data_directory = '/var/lib/postgresql/10/main'      # use data in another directory" ]]
>   then echo "${REPLY/\'*\'/'${path}'}"
>   else echo "${REPLY}"
>   fi
> done < postgresql.conf

# This is a comment
log_connections = yes
log_destination = 'syslog'
search_path = '"$user", public'
shared_buffers = 128MB
data_directory = '/newpath'      # use data in another directory
# This is a comment

Upvotes: 3

thb
thb

Reputation: 14434

REPLACEMENT_PATH=mypath
sed -i path/postgresql.conf -re "s/^(data_directory[[:space:]]*=[[:space:]]*')[^']*(')/\1${REPLACEMENT_PATH}\2/"

Upvotes: 1

Related Questions