这个sed语法是什么意思? " S / MY_BASE_DIR = \(* \。)/ MY_BASE_DIR = $ {MY_BASE_DIR- \ 1} /"

时间:2016-04-26 06:51:19

标签: bash sed

这是一个简单的问题,但我无法在教程中找到它。任何人都可以解释一下这个语句在包含.sh脚本的文件夹中的bash shell中执行时的作用。我知道-i做了编辑,我知道它将在当前目录中的所有脚本上运行sed。而且我知道它会做某种替代。但这\(.*\)是什么意思?

sed -i 's/MY_BASE_DIR=\(.*\)/MY_BASE_DIR=${MY_BASE_DIR-\1}/' *.sh

提前致谢。

3 个答案:

答案 0 :(得分:7)

你有一个表达式:

sed -i 's/XXX=\(YYY\)/XXX=ZZZ/' file

这会在文件中查找字符串XXX=并捕获后续内容。然后,它将此捕获的内容替换为ZZZ。由于存在捕获的组,因此可以使用\1访问它。最后,使用-i中的sed标记可使版本就位。

对于替换,它使用Shell parameter expansion中描述的以下语法:

  

<强> $ {参数:-word}

     

如果参数未设置或为null,则替换单词的扩展。   否则,参数的值将被替换。

示例:

$ d=5
$ echo ${d-3}
5
$ echo ${a-3}
3

对于${MY_BASE_DIR-SOMETHING-\1},您说:打印$MY_BAS_DIR。如果此变量未设置或为null,则打印\1中存储的内容。

总之,这是将MY_BASE_DIR重置为变量$MY_BASE_DIR中的值,除非未设置此值;在这种情况下,价值保持不变。

请注意,除非您使用双引号,否则不会扩展该变量。

测试:

$ d=5
$ cat a
d=23
blabla
$ sed "s/d=\(.*\)/d=${d-\1}/" a   # double quotes -> value is replaced
d=5
blabla
$ sed 's/d=\(.*\)/d=${d-\1}/' a   # single quotes -> variable is not expanded
d=${d-23}
blabla

如果未设置$d,Andd会看到值是如何保持不变的:

$ unset d
$ sed "s/d=\(.*\)/d=${d-\1}/" a
d=23

答案 1 :(得分:3)

脚本包含这样的行:

MY_BASE_DIR=/usr/local

sed表达式将它们更改为:

MY_BASE_DIR=${MY_BASE_DIR-/usr/local}

效果是/usr/local不用作固定值,而只用作默认值。您可以通过设置环境变量MY_BASE_DIR来覆盖它。

答案 2 :(得分:2)

为了将来参考,我会看一下ExplainShell网站:

http://explainshell

这将为您提供命令结构的细分等。在这种情况下,让我们逐步完成细节......让我们从一个简单的例子开始,让我们假设我们要制作简单的改变 - 通过添加&#34;#&#34;来评论所有行。在每一行之前。我们可以使用&#34; .sh&#34;对目录中的所有*.sh文件执行此操作。当前目录中的扩展名:

sed 's/^/\#/' *.sh

即。使用^ ...

替换行#的开头

警告:您没有指定您正在使用的操作系统。使用不同版本的sed和OS可能会得到不同的结果...

好的,现在我们可以深入研究脚本中的替换。一个例子可能更容易解释:

File: t.sh
MY_BASE_DIR="/important data/data/bin"

命令's/MY_BASE_DIR=\(.*\)/MY_BASE_DIR=${MY_BASE_DIR-\1}/' *.sh

将在目录中的每个.sh文件中搜索"MY_BASE_DIR"

当遇到字符串"MY_BASE_DIR=.*"时,在文件中,它会将其展开为MY_BASE_DIR="/important data/data/bin",现在将其替换为表达式/MY_BASE_DIR=${MY_BASE_DIR-\1}/的右侧,后者变为

MY_BASE_DIR=${MY_BASE_DIR-"/important data/data/bin"}

基本上发生的是替代操作需要

MY_BASE_DIR =&#34; /重要数据/数据/箱&#34;

并插入

MY_BASE_DIR = $ {MY_BASE_DIR - &#34; /重要数据/数据/ bin&#34; }

现在如果我们使用变量MY_BASE_DIR set

运行脚本

导出MY_BASE_DIR =&#34; / new / import / dir&#34;

由引用的sed脚本修改的脚本现在将 / important / data / bin 替换为 / new / import / dir ...