修改路径

修改路径

我正在尝试通过 修改存储在变量 ( $var)中的路径sed。事实上,$(dirname "$var")由于与脚本用途相关的原因,我需要进行替换。

的一个示例varvar=/dir/dir xyz/file.txt, whilefilename包含多个要替换的路径,这些路径可以位于任何位置(一次位于行的中间附近,另一条位于行首,等等)。下面我尝试举一个例子filename

dog foo/bar /dir/dir xyz/file.txt
a b c d /dir/dir xyz/file.txt x y z
/dir/dir xyz/file.txt 1234
{[(/dir/dir xyz/file.txt

我想要的是

dog foo/bar .
a b c d . x y z
. 1234
{[(.

我尝试了以下方法

sed "s|"$(dirname "$var")"|.|g" "$filename"

获得sed: -e expression #1, char 31: unterminated `s' command

你可以帮帮我吗?当然,除了 之外,您还可以建议其他方式sed

答案1

在:

sed "s|"$(dirname "$var")"|.|g" "$filename"

和被引用,但 不在s|引号内,因此受到 split+glob 的影响。|.|g$(dirname "$var")

sed -e "s|$(dirname -- "$var")|.|g" -- "$filename"

会修复这个问题(也添加缺少的s),但这仍然是错误的,因为in--的左侧被解释为正则表达式(更不用说如果包含字符,您可能会遇到严重的问题;并且适用于文本,而不保证文件名是)。s/lhs/rhs/flagssed$var|sed

例如,.匹配任何字符,而不仅仅是.

你应该这样做:

DIR="$(dirname -- "$var")" perl -pe 's/\Q$ENV{DIR}\E/./g' < "$filename"

以便可以使用任意文件路径。


严格来说,对于任意文件路径,包括包含换行符的文件路径,我们需要添加选项-0777(slurp 模式),perl并且不能使用删除尾随换行符的命令替换。这可以通过将完整的内容传递$varperl并使用 perl dirname()(来自File::Basename模块)来完成。

答案2

这似乎是您想要做的所有事情,使用任何 sed 并假设您的变量不包含任何:s:

$ var='/dir/dir xyz/file.txt'
$ sed "s:$var:.:" file
dog foo/bar .
a b c d . x y z
. 1234
{[(.

我不知道你为什么打电话来dirname。另外,如果您不打算将我们/作为 sed 分隔符,请不要使用像这样的正则表达式元字符,|因为这最多只会混淆您的代码,请选择一个像:始终是文字的字符。并且不要对非环境变量使用全大写的变量名称,请参阅正确的 bash 和 shell 脚本变量大写

给定你的评论dirname,如果您确实因某种原因需要打电话,那么您可以这样做:

$ sed "s:$(dirname "$var"):.:" file
dog foo/bar ./file.txt
a b c d ./file.txt x y z
./file.txt 1234
{[(./file.txt

相关内容