递归批量更新符号链接

ggu*_*erg 15 linux symbolic-link

我有一个网络应用程序,它在整个子目录中有一堆符号链接。我需要将应用程序移动到另一个目录结构,并且需要更新所有符号链接以指向新路径。例如:

旧目录:/home/user/public_html/dev
新目录:/home/user/public_html/qa
旧符号链接:/home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/dev/images
新符号链接:/home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/qa/images

问题是有很多这些分散在各种目录中。如何从根递归搜索并重新创建指向/dev/with 的所有符号链接/qa/

Dav*_*d Z 23

这个 bash 命令应该为你做:

find /home/user/public_html/qa/ -type l -lname '/home/user/public_html/dev/*' -printf 'ln -nsf "$(readlink "%p" | sed s/dev/qa/)" "$(echo "%p" | sed s/dev/qa/)"\n' > script.sh
Run Code Online (Sandbox Code Playgroud)

它用于find标识qa目录中所有与目录中目标符号链接的dev文件,并且对于每个文件,它打印出一个 bash 命令,该命令将用指向qa/. 运行后,只需执行生成的脚本

bash script.sh
Run Code Online (Sandbox Code Playgroud)

您可能想先手动检查它以确保它有效。

这是上述find命令的更详细版本,以便于阅读(尽管在实践中我不一定会这样写):

SRC_DIR="/home/user/public_html/qa"
OLD_TARGET="/home/user/public_html/dev"
SUB="s/dev/qa/"

find $SRC_DIR -type l \
  -lname "$OLD_TARGET/*" -printf \
  'ln -nsf "$(readlink "%p"|sed $SUB)" "$(echo "%p"|sed $SUB)"\n'\
 > script.sh
Run Code Online (Sandbox Code Playgroud)


小智 6

如果其他人在搜索解决方案时发现了这一点:创建一个名为“linkmod.sh”的文件,其中包含:

#!/bin/sh
PATTERN1=`echo "$2"`
PATTERN2=`echo "$3"`
LINKNAME=`echo "$1"`
OLDTARGET=`readlink "$1"`
NEWTARGET=`echo "$OLDTARGET" \
| sed -e 's/'"$PATTERN1"'/'"$PATTERN2"'/'`
echo ln -nsf "$NEWTARGET" "$LINKNAME"
Run Code Online (Sandbox Code Playgroud)

并运行

find . -type l -print0 | xargs -0IX echo linkmod.sh X "pattern1" "pattern2"
Run Code Online (Sandbox Code Playgroud)

如果需要,您可以在 find 中使用 -lname 选项。

注意:在 sed 中需要 \ 的任何字符之前,您必须在模式中使用 2x \,因为 echo 删除了一个。例如

find . -type l -print0 | xargs -0IX echo linkmod.sh X "folder\\ name\\/file" "folder2\\ name\\/file"
Run Code Online (Sandbox Code Playgroud)

echo如果 ln 命令正确,则从最后一行中删除。