符号链接新目标

符号链接新目标

我想将指向当前目录的符号链接更改为名为 /pool 的公共目录

当前目录a/b 公共目录a/pool

我遵循了我能找到的所有内容,并最终完成了这个脚本。

#!/bin/sh
from="$1"
to="$2"
shift 2
for i
do
  a=$(readlink "$i") && ln -sf "$(echo $a | sed "s@$from@$to@")" "$i"
done

在运行脚本之前...

lrwxrwxrwx 1 neysa neysa  18 Jan  4 22:03 xfsm-logout.png -> system-log-out.png
lrwxrwxrwx 1 neysa neysa  17 Jan  4 22:03 zoom-best-fit.png -> zoom-fit-best.png

运行脚本 ./rename-links 后。 ../水池/

lrwxrwxrwx 1 neysa neysa  25 Jan  4 22:31 xfsm-logout.png -> ../pool/ystem-log-out.png
lrwxrwxrwx 1 neysa neysa  24 Jan  4 22:31 zoom-best-fit.png -> ../pool/oom-fit-best.png

它可以工作,但有一个错误,缺少目标的第一个字母。我究竟做错了什么?

答案1

. 是正则表达式元字符sed,它匹配任何单个字符。因为您只是$from直接将路径插入到正则表达式中,所以.就像您编写的那样:

sed "s@.@../pool/@"

你自己。那取代任何单个字符,一次带有“ ../pool/”,因此它具有删除第一个字符并在其位置插入“../pool/”的效果。

如果您readlink手动运行该命令,您会发现这./不是链接内容的一部分 - 您的ls显示是相同的。

您至少需要.在脚本中使用特殊情况下的“”,因为它可能会也可能不会出现在链接内容中。一种选择是使用readlink -f在链接和上.- 这将为您提供两者的绝对路径 - 但如果您只需要处理单一情况,则还有更简单的选择。


如果你在里面,你就可以完全bash离开sed使用基本参数扩展:

ln -sf "${a/$from/$to}" "$i"

这将用in$from的扩展取代 的扩展,并按字面意思处理(尽管和其他$to$a.*使用元字符 - 实际上应该"${a/"$from"/"$to"}"避免这种情况)。总体而言,这是一种更干净、更简单的方法。

相关内容