在bash脚本中使用sed搜索并修改

Jam*_*ess 1 bash sed

我正在尝试使用脚本编辑 postgres 配置文件

我想搜索一下是否

listen_addresses = '*' 已经存在或不存在。如果已经存在,则不执行任何操作;如果确切的字符串不存在,则使用以下规则添加条目

如果有任何配置行带有listen_addresses“*”存在的任何其他值,那么我需要用注释对该行进行注释 Commented out on DD-MM-YYYY by XYZ ,然后添加一个新行, listen_addresses = '*' 后跟注释

Added on DD-MM-YYYY by XYZ
Run Code Online (Sandbox Code Playgroud)

我尝试过的是这样的事情:

sed -i 's/^#?listen_addresses .*/listen_addresses = '*'/'  /etc/postgresql/9.3/main/postgresql.conf
Run Code Online (Sandbox Code Playgroud)

但这无助于添加注释,并且只会 listen_addresses = *由于缺少转义字符而插入。

我不知道如何完成这个改变。

Tes*_*ler 5

  • 如果它不存在,您想首先将其注释掉吗?听起来很矛盾,但是呃。

  • 任何以 Listen_addresses 开头且具有任何其他值的行- 匹配“[this]后面不跟着[that]”需要负向前视,正则sed表达式不支持此功能。

  • sed逐行处理,这使得搜索整个文件然后决定是否进行更改变得困难。

如果您执行以下任一操作,这会容易得多:

a) 注释掉每一 listen_address =行,无论它是否正确,然后总是在文件末尾添加一个新行:

sed -i "s/^\(listen_addresses .*\)/# Commented out by Name YYYY-MM-DD \1/" postgresql.conf
echo "listen_addresses = '*'" >> postgresql.conf
Run Code Online (Sandbox Code Playgroud)

如果您定期运行此脚本,这会很烦人,因为文件会永远增长。

或者

b) 使用 以外的工具sed。但你没有说你有任何其他可用的工具。Grep 会让事情变得更容易,Perl 甚至更容易。但坚持使用 sed (和 bash),上面的变体怎么样:

# Comment out every listen_address line:
sed -i "s/^\(listen_addresses .*\)/#\1 Commented out by Name YYYY-MM-DD/" postgresql.conf

# Try to uncomment a correct one:
sed -i "s/^#\(listen_addresses = '\*'\).*/\1/" postgresql.conf

# Check if the correct one exists, and if it doesn't, add it:
if ! sed -n -e "/^listen_addresses = '\*'/!ba;Q0;:a;\$Q1" postgresql.conf ; then
  echo "listen_addresses = '*'" >> postgresql.conf
fi
Run Code Online (Sandbox Code Playgroud)

编辑

好的,受约束的 sed 只是有趣,但这是更简单的逻辑,并在注释后添加新行。

#!/bin/env bash

if grep -q "^listen_addresses = '\*'" postgresql.conf ; then
    echo "Correct listen_addresses found, doing nothing"
    exit
fi

if ! grep -q "^listen_addresses =.*" postgresql.conf ; then
    echo "No listen_addresses found, adding one at the end"
    echo "listen_addresses = '*'" >> postgresql.conf
    exit
fi

if grep -q "^listen_addresses =.*" postgresql.conf ; then
    echo "Wrong listen_addresses found, commenting them out"
    sed -i "s/^\(listen_addresses.*\)/#\1 Commented out by Name YYYY-MM-DD/" postgresql.conf

    echo "Adding correct one"
    sed -i "/^#listen_addresses/a listen_addresses = '\*'" postgresql.conf
fi
Run Code Online (Sandbox Code Playgroud)