[英]How change symlink path for many files?
I was changed directory name.我是改了目录名。 In this directory thousands of files.
在这个目录中有数千个文件。 Some projects use this files, projects have got symlinks on it.
一些项目使用这个文件,项目有符号链接。
if 2 only bash scripting with deleting and creating new - i will do it, but may be you know more easy way?如果 2 只有删除和创建新的 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 ).这有点复杂,但可以通过
find
、 readlink
、检查符号链接是否是相对的,以及sed
来摆脱路径名中的..
(从这个答案中以1:1 复制)来完成。
(Note that most convenient methods (such as readlink -f
) are not available due to the symlinks targets not existing anymore.) (请注意,由于符号链接目标不再存在,最方便的方法(例如
readlink -f
)不可用。)
Assuming your old path is /var/lib/old/path
:假设您的旧路径是
/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 "ta")"; fi; if [ "${p:0:'${#oldpath}'}" == "'"$oldpath"'" ]; then ...; fi;' \\;
Now replace the ...
from above with ln -sf
( -f
to override the existing link).现在用
ln -sf
( -f
覆盖现有链接)替换上面的...
。
Assuming your new path is /usr/local/my/awesome/new/path
:假设您的新路径是
/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 "ta")"; fi; if [ "${p:0:'${#oldpath}'}" == "'"$oldpath"'" ]; then ln -sf "'"$newpath"'${p:'${#oldpath}'}" "{}"; fi;' \\;
Note that oldpath
and newpath
have to be absolute paths.请注意,
oldpath
和newpath
必须是绝对路径。
Also note that this will convert all relative symlinks to absolute ones.另请注意,这会将所有相对符号链接转换为绝对符号链接。
It would be possible to keep them relative, but only with a lot of effort.将它们保持相对是可能的,但需要付出很多努力。
For those of you who care what that one-line-inferno actually means:对于那些关心单行地狱实际上意味着什么的人:
find
- a cool executable find
- 一个很酷的可执行文件/
- where to search, in this case the system root /
- 搜索位置,在本例中为系统根目录-type l
- match symbolic links -type l
- 匹配符号链接-execdir
- for every match run the following command in the directory of the matched file: -execdir
- 对于每个匹配项,在匹配文件的目录中运行以下命令:
bash
- well, bash bash
- 好吧,bash-c
- execute the following string (leading and trailing '
removed): -c
- 执行以下字符串(前导和尾随'
已删除):
p="$(readlink "{}")";
- starting with the most inner: "
- start a string to make sure no expansion happens "
- 开始一个字符串以确保不会发生扩展{}
- placeholder for the matched file's name (feature of -execdir
) {}
- 匹配文件名的占位符( -execdir
功能)"
- end the string "
- 结束字符串readlink ...
- find out where the symlink points to readlink ...
- 找出符号链接指向的位置p="$(...)"
- and store the result in $p
p="$(...)"
- 并将结果存储在$p
if [ "${p:0:1}" != "/" ]; then
if [ "${p:0:1}" != "/" ]; then
- if the first character of $p
is /
(ie the symlink is absolute), then... if [ "${p:0:1}" != "/" ]; then
- 如果$p
的第一个字符是/
(即符号链接是绝对的),那么...p="$(echo "$(pwd)/$p" | sed -e "s|/\\./|/|g" -e ":a" -e "s|/[^/]*/\\.\\./|/|" -e "ta")";
- convert the path to an absolute one: $(pwd)
- the current directory (where the matched file lies, because we're using -execdir
) $(pwd)
- 当前目录(匹配文件所在的目录,因为我们使用的是-execdir
)/$p
- append a slash and the target of the symlink to the path of the working directory /$p
- 将斜杠和符号链接的目标附加到工作目录的路径echo "$(pwd)/$p" |
- pipe the above to the next command sed ...
- resolve all ..
's, see here sed ...
- 解决所有..
的问题,请参见此处p="$(...)"
and store the result back into $p
. p="$(...)"
并将结果存储回$p
。fi;
- end if
if
if [ "${p:0:'${#oldpath}'}" == "'"$oldpath"'" ];
- if $p
starts with $oldpath
$p
以$oldpath
${p:0:'${#oldpath}'}
- substring of $p
, starting at position 0
, with length of $oldpath
: ${p:0:'${#oldpath}'}
- $p
子字符串,从位置0
开始,长度为$oldpath
:
${#oldpath}
- length of variable $oldpath
${#oldpath}
- 变量$oldpath
长度'...'
- required because we're inside a '
-quoted string '...'
- 必需,因为我们在一个'
引用的字符串中then
- then... then
——然后……ln -sf
- link symbolically and override existing file, with arguments: ln -sf
- 符号链接并覆盖现有文件,带参数:
"'"$newpath"'${p:'${#oldpath}'}"
- replace the $oldpath
part of $p
with $newpath
(actually remove as many characters from $p
as $oldpath
long is, and prepend $newpath
to it): "'"$newpath"'${p:'${#oldpath}'}"
- 用$newpath
替换$p
的$oldpath
部分(实际上从$p
删除与$oldpath
long 一样多的字符,并在前面加上$newpath
):
"
- start a string "
- 开始一个字符串'
- end the '
-string argument to bash -c
'
- 结束'
-string 参数到bash -c
"
- append a "
-string to it (in which variable expansion happens), containing: "
- 附加一个"
-string 到它(其中发生变量扩展),包含:$newpath
- the value of $newpath
$newpath
-价值$newpath
"
- end the "
-string argument to bash -c
"
- 结束"
-string 参数给bash -c
'
- append a '
-string to it, containing: '
- 附加一个'
-string 到它,包含:${p:
- a substring of p
, starting at: ${p:
-的一个子p
,起始于:'
- end the argument to bash -c
'
- 结束参数bash -c
${#oldpath}
- append the length of $oldpath
to it ${#oldpath}
- 附加$oldpath
的长度'
- append another '
-string to it '
- 附加另一个'
-string}
- end substring }
- 结束子串"
- end string "
- 结束字符串"{}"
- the link file, whose path stays the same "{}"
- 链接文件,其路径保持不变fi;
- end if
if
\\;
- delimiter for -execdir
-execdir
分隔符
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.