找到一个目录的所有符号链接并将目标更改为另一个目录

Bel*_*dez 6 find symlink

我有一大堆符号链接的/home在文件和子目录/foo。我想定位新目录/bar.

我的方法是查看所有无效的符号链接并验证它们是否指向/foo. 然后我做了以下事情:

sudo find . -type l -! -exec test -e {} \; -exec sh -c '\
   old_link_target=$(readlink "$0"); \
   new_link_target=${old_link_target//foo/bar}; \
   ln -snf $new_link_target $0' {} \;
Run Code Online (Sandbox Code Playgroud)

但是,我想要一种更精确的方法,它不包括将目光放在无效符号链接上的初始步骤。所以,为了这个问题,假设/foo仍然存在,所以需要另一种方法。

Sté*_*las 8

GNUly:

find . -lname '/foo*' -printf '%p\0%l\0' |
  awk -vRS='\0' '
    {
      getline target
      sub("^/foo", "/bar", target)
      printf("%s\0%s\0", target, $0)
    }' |
  xargs -r0n2 ln -sfT
Run Code Online (Sandbox Code Playgroud)

或者使用最近的 GNU sed

find . -lname '/foo*' -printf '%l\0%p\0' |
  sed -z 's|^/foo|/bar|;n' |
  xargs -r0n2 ln -sfT
Run Code Online (Sandbox Code Playgroud)

请注意,您可能会影响符号链接的所有权(例如,如果它们位于不属于他们的目录中,但具有写入权限并拥有t位设置(如/tmp))。

为了防止这种情况,您可以改用 GNU tar

find . -lname '/foo*' -print0 |
  tar --null -T - -cf - --transform='s@^/foo@/bar@' |
  tar xpf -
Run Code Online (Sandbox Code Playgroud)