Sed用变量中的行替换行

时间:2016-09-29 10:45:30

标签: bash sed

我是新来的,我有一个问题我无法弄明白。我试图用几乎相同的行替换* .txt文件中的一行但修改。我仍然得到错误或输出文件没有改变。你能帮我吗?

脚本:

var1=`grep "keyS.log\" type=" /C/tst/tst.txt`
x="<\!--"
if echo "$var1" | grep -q "$x"; then
   echo "Already disabled";
else
 prefix='<!-- '
 sufix='-->'
 modified=`echo "${var1/[[:space:]]/}" | sed 's:^.\(.*\).$:\1:'`
 final="${prefix}${modified}${sufix}"
 echo "${final}"
 `sed -i 's/${var1}/${final}/g' /C/tst/tst.txt`
fi

我试图在文件中修改的行是这样的:

<category="keyS" priority="1" appender="/tmp/keyS.log"/>

应该是这样的:

<!-- category="keyS" priority="1" appender="/tmp/keyS.log"/-->

还有更多以类别开头的行,并且appender背后可能有不同的路径=所以它是动态的。

错误就像: sed:1:“/ C /tst / tst.txt”:未定义标签'st / tst.txt'

当我尝试使用

cat /C/tst/tst.txt  |  sed 's/${var1}/${final}/g' >> /C/tst/tsttmp.txt

在tsttmp.txt中没有更改行,我也丢失了行间距,因此整个文本是一行。

提前感谢您的任何帮助

斯坦尼斯

2 个答案:

答案 0 :(得分:2)

shell用于调用工具和操作文件/进程,而不是用于操作文本。标准的UNIX通用文本操作工具是awk。将您的shell脚本翻译成awk it's:

awk '
/keyS.log" type=/ {
    if ( /<!--/ ) {
        print "Already disabled" |"cat>&2"
    }
    else {
        sub(/</,"<!-- ")
        sub(/>/,"-->")
    }
}
1' /C/tst/tst.txt

awk -i inplace 'script' file与GNU awk或awk 'script' file > tmp && mv tmp file与其他awks一起使用以覆盖原始文件。

请注意,您发布的示例输入keyS.log" type=中的脚本中的正则表达式<category="keyS" priority="1" appender="/tmp/keyS.log"/>并不存在,因此您必须将其更改为如果您发布的样本输入是准确的。

答案 1 :(得分:1)

如果我理解你的问题,请按下列要求:

sed 's/^<\(category=.*keyS.log.*\)>$/<!-- \1-->/' /C/tst/tst.txt

sed模式

  • 查找以<开头,后跟category的行。如果已经注释掉,则会忽略,因为在这种情况下<将不会跟category
  • 放在()中的模式将存储为\1(依此类推)。我们在这里寻找keyS.log
  • 如果发生上述两场比赛,替换部分将添加html风格的评论。

注意:我没有使用sed的-i选项进行内联替换。一旦您确定这适合您就可以使用它。