我更改了目录名称。 在这个目录中有数千个文件。 有些项目使用这个文件,项目上有符号链接。
如果只有2个bash脚本用删除和创建新 - 我会这样做,但你可能知道更简单的方法吗?
答案 0 :(得分:11)
它有点复杂,但可以使用find
,readlink
来检查,以检查符号链接是否相对,以及sed
摆脱路径名中的..
(从this answer复制1:1)
(请注意,由于符号链接目标不再存在,大多数方便的方法(例如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
必须是绝对路径
另请注意,这会将所有相对符号链接转换为绝对符号
可以让他们保持相对,但只需付出很多努力。
对于那些关心一线地狱实际意味着什么的人:
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 ...
- 解析所有..
,请参阅here 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}'}"
- 将$oldpath
的{{1}}部分替换为$p
(实际上从$newpath
移除尽可能多的字符$p
,并在其前加$oldpath
):
$newpath
- 开始一个字符串"
- 结束'
- 字符串参数'
bash -c
- 向其附加"
- 字符串(其中发生变量扩展),包含:"
- $newpath
$newpath
- 结束"
- 字符串参数"
bash -c
- 在其中添加'
- 字符串,其中包含:'
- ${p:
的子字符串,从:p
- 结束'
bash -c
- 将${#oldpath}
的长度附加到$oldpath
- 向其添加另一个'
- 字符串'
- 结束子字符串}
- 结束字符串"
- 链接文件,其路径保持不变"{}"
- 结束fi;
if
- \;