我已经更改了目录名字。
在这个目录中有成千上万的文件。
一些项目使用这些文件,这些项目有符号链接指向它们。
- 如何查找所有符号链接,其中地址中包含文件夹名字?
- 如何以自动模式更改所有这些符号链接到另一个路径?
如果只用bash脚本删除和创建新的方式-我可以做到,但是也许您知道更简单的方法?
It's a bit complicated, but it can be done with find
, readlink
, a check to test whether the symlink is relative or not, and sed
to get rid of ..
in path names (copied 1:1 from this answer).
(Note that most convenient methods (such as readlink -f
) are not available due to the symlinks targets not existing anymore.)
Assuming your old path is /var/lib/old/path
:
oldpath='/var/lib/old/path';
find / -type l -execdir bash -c 'p="$(readlink "{}")"; if [ "${p:0:1}" != "/" ]; then p="$(echo "$(pwd)/$p" | sed -e "s|/\./|/|g" -e ":a" -e "s|/[^/]*/\.\./|/|" -e "t a")"; fi; if [ "${p:0:'${#oldpath}'}" == "'"$oldpath"'" ]; then ...; fi;' \;
Now replace the ...
from above with ln -sf
(-f
to override the existing link).
Assuming your new path is /usr/local/my/awesome/new/path
:
oldpath='/var/lib/old/path';
newpath='/usr/local/my/awesome/new/path';
find / -type l -execdir bash -c 'p="$(readlink "{}")"; if [ "${p:0:1}" != "/" ]; then p="$(echo "$(pwd)/$p" | sed -e "s|/\./|/|g" -e ":a" -e "s|/[^/]*/\.\./|/|" -e "t a")"; fi; if [ "${p:0:'${#oldpath}'}" == "'"$oldpath"'" ]; then ln -sf "'"$newpath"'${p:'${#oldpath}'}" "{}"; fi;' \;
oldpath
和newpath
必须是绝对路径。对于那些关心这个一行代码到底是什么意思的人:
find
- 一个很酷的可执行文件/
- 要搜索的位置,在这个例子中是系统根目录-type l
- 匹配符号链接-execdir
- 对于每一个匹配项,在匹配到的文件所在的目录下运行以下命令:
bash
- 好吧,bash-c
- 执行下面的字符串(前后的'
被移除):
p="$(readlink "{}")";
- 从最内部开始:
"
- 开始一个字符串以确保没有扩展发生{}
- 匹配文件名的占位符(使用-execdir
的特性)"
- 结束字符串readlink ...
- 找出符号链接指向哪里p="$(...)"
- 并将结果存储在$p
中if [ "${p:0:1}" != "/" ]; then
- 如果$p
的第一个字符不是/
(即符号链接是绝对路径),则...
p="$(echo "$(pwd)/$p" | sed -e "s|/\./|/|g" -e ":a" -e "s|/[^/]*/\.\./|/|" -e "t a")";
- 将路径转换为绝对路径:
$(pwd)
- 当前目录(因为我们使用了-execdir
,所以匹配的文件位于其中)/$p
- 将斜杠和符号链接的目标附加到工作目录的路径中echo "$(pwd)/$p" |
- 将上述内容传递给下一个命令sed ...
- 解析所有..
,请参见这里p="$(...)"
并将结果存回$p
fi;
- 结束if
if [ "${p:0:'${#oldpath}'}" == "'"$oldpath"'" ];
- 如果$p
以$oldpath
开头
${p:0:'${#oldpath}'}
- $p
的子字符串,从位置0
开始,长度为$oldpath
:
${#oldpath}
- 变量$oldpath
的长度'...'
- 必需,因为我们在一个'
-引用字符串中then
- 然后...ln -sf
- 符号链接并覆盖现有文件,参数为:
"'"$newpath"'${p:'${#oldpath}'}"
- 用$newpath
替换$p
的$oldpath
部分(实际上是从$p
中删除与$oldpath
长度相同的字符,并将$newpath
添加到其中):
"
- 开始字符串'
- 结束传递