我在脚本文件中有一个路径,就像
export DATABASE_XML=/mnt/nfs/reg_work/work_dir/dexter/DUMP/REX-9999/Test_Database.xml
我需要将行/mnt/nfs/reg_work/work_dir/dexter/DUMP/REX-9999
替换为另一行文本
$(dirname $(pwd -P))
使行看起来像..
export DATABASE_XML=$(dirname $(pwd -P))/Test_Database.xml
尝试使用sed进行操作,但是我被卡住了... 任何帮助将不胜感激。...
答案 0 :(得分:1)
您可以阅读sed
正则表达式上的文档,以了解各种用于匹配字符串的结构。
这是处理脚本的一种方法:
sed "s/DATABASE_XML=.*\/\([^/]*\)$/DATABASE_XML=\$(dirname \$(pwd -P))\/\1/"
首先,让我们看一下匹配的正则表达式:
DATABASE_XML=.*\/\([^/]*\)$
在.*
之后,*
将与任何字符(.
的零个或多个(DATABASE_XML=
)匹配,直到找到斜线(\/
,由于/
被用作搜索/替换定界符而被转义,并且非*
(/
的零个或多个([^/]
)定义了一组字符使用[
和]
,而^
的意思是“不是”,唯一的组成员是/
)。因此[^/]
是除/
以外的任何字符,而*
表示其中任意数目。我们将其与\(
和\)
分组,以便我们可以在替换字符串中引用此处捕获的内容,因为它代表了我们要保留的文件名。因此,匹配(并捕获)现有文件名的正则表达式看起来像\([^/]*\)
。
替换字符串为:
DATABASE_XML=\$(dirname \$(pwd -P))\/\1
我们对$
进行了转义,因为shell或sed
可能会将它们解释为特殊字符。我们希望他们在替换中仅表示$
。 \/
只是一个斜杠,再次被转义了,因为否则它会被sed
混淆为搜索/替换定界符。剩下\1
。 \1
替换为搜索正则表达式字符串的\(
和\)
对中匹配的内容,在这种情况下为文件名。
答案 1 :(得分:0)
使用sed进行替换。您可以选择任何字符作为s
命令分隔符。下面我使用#
:
sed 's#/mnt/nfs/reg_work/work_dir/dexter/DUMP/REX-9999#$(dirname $(pwd -P))#'
示例:
$ export DATABASE_XML=/mnt/nfs/reg_work/work_dir/dexter/DUMP/REX-9999/Test_Database.xml
$ sed 's#/mnt/nfs/reg_work/work_dir/dexter/DUMP/REX-9999#$(dirname $(pwd -P))#' <<<"$DATABASE_XML"
$(dirname $(pwd -P))/Test_Database.xml
您也可以选择扩展命令替换,方法是不将命令替换用'
引起来:
$ sed 's#/mnt/nfs/reg_work/work_dir/dexter/DUMP/REX-9999#'"$(dirname $(pwd -P))"'#' <<<"$DATABASE_XML"
/home/Test_Database.xml
您可以将路径存储在变量中:
$ subst=/mnt/nfs/reg_work/work_dir/dexter/DUMP/REX-9999
$ sed 's#'"$subst"'#'"$(dirname $(pwd -P))"'#' <<<"$DATABASE_XML"
/home/Test_Database.xml
唯一需要关注的是对sed
的{{1}}命令使用分隔符,例如这样的字符,该字符不会出现在替换字符串中。如果确实需要,可以在s
命令分隔符中使用不可读的字符,以最大程度地减少危险(谁使用s
字符命名文件?)在这里,我使用不可读的$'\xff'
十六进制值对于0xff
命令分隔符:
s