需要使用Shell脚本替换文件中的特定行

时间:2018-12-17 12:14:48

标签: bash shell ubuntu

我正在尝试使用shell脚本从postgresql.conf替换下一行的path部分:

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

我首先使用下面的脚本检查了是否能够首先找到该行,但是找不到该行:

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

我知道有一种更好的方法,可以使用sed替换该行,但是我需要通过从头到尾读取文件然后替换该行的所需部分(如果找到)来了解其是否可行。如果不是这样,只需更改path部分即可替换整行。谢谢!

3 个答案:

答案 0 :(得分:3)

普通bash解决方案:

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

测试:

$ 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

答案 1 :(得分:2)

另一种使用case-*的方法允许在等号前后以及在任何注释之前使用非精确的间距,但是引入错误匹配的可能性很小。我认为该行中的其他特定信息足够小,因此没有问题。

$: 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.

如果很好,那么

mv /tmp/checkme postgresql.conf

您可以对其进行几次测试,然后使其自动进行,但是除非您正在构建该自动化工具,否则我将亲自对其进行检查。

答案 2 :(得分:1)

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