sed在bash中使用变量取消注释多行

时间:2016-12-22 12:55:45

标签: linux unix awk

我遇到以下问题:我试图从我确定使用的特定行中取消注释:

LINESTART=$(grep -nr "matching string" test.conf | cut -d : -f1)

之后,我需要取消注释代码中从$LINESTART$((LINE+10))

的部分
LINEEND=$((LINE+10))

我尝试了以下sed语法:

sed -i '${LINESTART},${LINEEND} s/# *//' test.conf

但是我收到以下错误:

sed: -e expression #1, char 4: extra characters after command

示例test.conf:

 84     #server {
 85     #    listen       8000;
 86     #    listen       somename:8080;
 87     #    server_name  somename  alias  another.alias;
 88 
 89     #    location / {
 90     #        root   html;
 91     #        index  index.php index.html index.htm;
 92     #    }
 93     #}

4 个答案:

答案 0 :(得分:3)

你可以尝试这个吗?

sed -i "${LINESTART},${LINEEND} s/# *//" test.conf

测试;

脚本:

#!/bin/bash
LINESTART=$(grep -nr "server {" test | cut -d : -f1 )
LINEEND=$((LINE+10))

sed "${LINESTART},${LINEEND} s/# *//" test

输出:

$ ./test.sh 
    server {
    listen       8000;
    listen       somename:8080;
    server_name  somename  alias  another.alias;

      location / {
      root   html;
      index  index.php index.html index.htm;
      }
      }

答案 1 :(得分:1)

在单引号中使用shell变量可防止它们被其值替换。使用双引号代替你应该达到你想要的效果:

$ cat file
# a0
# a1
# a2
# a3

$ S=2
$ E=3

$ sed "${S},${E}s/# *//" file
# a0
a1
a2
# a3

答案 2 :(得分:0)

如果您想备份实际的test.conf,尽管在文件本身中使用sed -I选项直接编辑它,那么以下内容可能对您有帮助。

LINESTART=$(grep -nr "matching string" test.conf | cut -d : -f1)
LINEEND=$((LINE+10))

awk -vlinestart="$LINESTART" -vlineend="$LINEEND" '{gsub(linestart,lineend,$0);print}' test.conf > test.conf_tmp
if [[ $? == 0 ]]
then
    mv test.conf test.conf_bkp
    mv test.conf_tmp test.conf
else
    echo "Please check there seems to be an issue as awk command didn't complete successfully."
fi

另外如果您可以展示一些示例test.conf,我会尝试在单个命令本身中执行此操作,让我知道它是如何进行的。

答案 3 :(得分:0)

不要这样做,只需使用awk就可以了:

$ awk '/location/{c=4} c&&c--{sub(/# */,"")} 1' file
 84     #server {
 85     #    listen       8000;
 86     #    listen       somename:8080;
 87     #    server_name  somename  alias  another.alias;
 88
 89     location / {
 90     root   html;
 91     index  index.php index.html index.htm;
 92     }
 93     #}

查找btw文件的命令名为find,而不是grep -r,就像GNU sed有-i进行就地编辑一样,如果需要,GNU awk有-i inplace它,所以这可能是你真正想要的:

$ find . -name 'file' -exec \
    awk -i inplace '/location/{c=4} c&&c--{sub(/# */,"")} 1' {} \;