这是一个简单的问题,但我无法在教程中找到它。任何人都可以解释一下这个语句在包含.sh脚本的文件夹中的bash shell中执行时的作用。我知道-i做了编辑,我知道它将在当前目录中的所有脚本上运行sed。而且我知道它会做某种替代。但这\(.*\)
是什么意思?
sed -i 's/MY_BASE_DIR=\(.*\)/MY_BASE_DIR=${MY_BASE_DIR-\1}/' *.sh
提前致谢。
答案 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网站:
这将为您提供命令结构的细分等。在这种情况下,让我们逐步完成细节......让我们从一个简单的例子开始,让我们假设我们要制作简单的改变 - 通过添加&#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 ...