我已更改目录名称。
在这个目录中有数千个文件。
一些项目使用此文件,项目上有符号链接(symbolic link)。
如果2只bash脚本具有删除和创建新的脚本-我会做到的,但是也许您知道更简单的方法吗?
最佳答案
find
,readlink
,检查符号链接(symbolic link)是否相对的检查以及sed
摆脱路径名中的..
(从this answer 1:1复制)来完成。(请注意,由于不再存在符号链接(symbolic link)目标,因此无法使用最方便的方法(例如
readlink -f
)。)假设您的旧路径是
/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;' \;
...
替换为ln -sf
(-f
覆盖现有链接)。假设您的新路径是
/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
必须是绝对路径。还要注意,这会将所有相对符号链接(symbolic link)转换为绝对符号链接(symbolic link)。
保持它们之间的相对性是可能的,但要付出很多努力。
分解
对于那些关心一线 hell 实际上意味着什么的人:
find
-一个很酷的可执行文件/
-搜索位置,在本例中为系统根-type l
-匹配符号链接(symbolic link)-execdir
-对于每个匹配项,在匹配文件的目录中运行以下命令:bash
-好吧,bash -c
-执行以下字符串(删除了开头和结尾的'
):p="$(readlink "{}")";
-从最内部开始:"
-启动字符串以确保不发生扩展{}
-匹配文件名的占位符(-execdir
的功能)"
-结束字符串readlink ...
-找出符号链接(symbolic link)指向p="$(...)"
-并将结果存储在$p
if [ "${p:0:1}" != "/" ]; then
-如果$p
的第一个字符是/
(即符号链接(symbolic link)是绝对的),则... p="$(echo "$(pwd)/$p" | sed -e "s|/\./|/|g" -e ":a" -e "s|/[^/]*/\.\./|/|" -e "t a")";
-将路径转换为绝对路径:$(pwd)
-当前目录(匹配的文件所在的位置,因为我们正在使用-execdir
)/$p
-将斜杠和符号链接(symbolic link)的目标附加到工作目录echo "$(pwd)/$p" |
-将以上内容传递给下一个命令sed ...
-解决所有..
的问题,请参见here p="$(...)"
并将结果存储回$p
中。 fi;
-结束if
if [ "${p:0:'${#oldpath}'}" == "'"$oldpath"'" ];
-如果$p
以$oldpath
开头${p:0:'${#oldpath}'}
-$p
的子字符串,从0
位置开始,长度为$oldpath
:${#oldpath}
-变量$oldpath
的长度'...'
-必需,因为我们在'
-引号字符串then
-然后... ln -sf
-符号链接(symbolic link)并使用参数覆盖现有文件:"'"$newpath"'${p:'${#oldpath}'}"
-用$oldpath
替换$p
的$newpath
部分(实际上从$p
中删除了与$oldpath
一样长的字符,并在其前面添加了$newpath
):"
-启动字符串'
-将'
-string参数结尾到bash -c
"
-向其附加"
-string(在其中发生变量扩展),其中包含:$newpath
-$newpath
的值"
-将"
-string参数结尾到bash -c
'
-向其附加一个'
-string,包含:${p:
-p
的子字符串,开始于:'
-结束bash -c
的参数${#oldpath}
-将$oldpath
的长度附加到它上面'
-向其附加另一个'
-string }
-结束子字符串"
-结束字符串"{}"
-链接文件,其路径保持不变fi;
-结束if
\;
--execdir
的分隔符关于linux - 如何更改许多文件的符号链接(symbolic link)路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31020219/