使用linux sed命令替换路径(使用特殊字符)

时间:2019-03-29 09:57:11

标签: shell

我在脚本文件中有一个路径,就像 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进行操作,但是我被卡住了... 任何帮助将不胜感激。...

2 个答案:

答案 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