linux - 如何更改许多文件的符号链接(symbolic link)路径?

标签 linux bash ln

我已更改目录名称。
在这个目录中有数千个文件。
一些项目使用此文件,项目上有符号链接(symbolic link)。

  • 如何查找所有符号链接(symbolic link),这些符号链接(symbolic link)的地址中都有文件夹名称?
  • 如何在自动模式下将所有这些符号链接(symbolic link)更改为另一个路径?

  • 如果2只bash脚本具有删除和创建新的脚本-我会做到的,但是也许您知道更简单的方法吗?

    最佳答案

  • 有点复杂,但是可以使用findreadlink,检查符号链接(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;' \;
    

  • 请注意,oldpathnewpath必须是绝对路径。
    还要注意,这会将所有相对符号链接(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/

    相关文章:

    Bash,总是在条件语句中回显

    linux - 如何在 Linux 中的 makefile 中创建指向目录的链接?

    linux - Bash:检查脚本是否已经在此计算机上运行

    c++ - 有没有像 "pthread_getcancelstate"这样的函数?

    linux - 一个 wav 后停止和循环 Shell。播放文件

    php - 在 MAMP 上安装 ffmpeg

    用于创建根符号链接(symbolic link)的 PHP exec 权限

    linux bash 查找如果不执行

    regex - 如何在 bash 中用单个空行替换多个空行?

    bash - 在bash中,如何批量显示文件中某行的文本?