如何有效地更改大量符号链接的目标?

时间:2019-02-28 17:17:07

标签: bash symlink batch-rename

因此,我有一个从Linux目录到同级目录的大约一千个符号链接的集合,这些符号链接用于重新组织一堆文件而不复制它们。

这是一个模拟我的情况的3个文件:

$ ls ref reorg -l
ref:
total 0
-rw-r----- 1 me 0 28 fév 11:57 a-foo.txt
-rw-r----- 1 me 0 28 fév 11:57 b-bar.txt
-rw-r----- 1 me 0 28 fév 11:57 c-baz.txt

reorg:
total 4
lrwxrwxrwx 1 me   16 28 fév 11:58 a.txt -> ../ref/a-foo.txt
lrwxrwxrwx 1 me   16 28 fév 11:58 b.txt -> ../ref/b-bar.txt
lrwxrwxrwx 1 me   16 28 fév 11:58 c.txt -> ../ref/c-baz.txt

现在,我意识到我应该创建一个更深的结构,所以我真正想要的是:

$ ls reorg/subdir/ -l
total 0
lrwxrwxrwx 1 me 19 28 fév 12:04 a.txt -> ../../ref/a-foo.txt
lrwxrwxrwx 1 me 19 28 fév 12:04 b.txt -> ../../ref/b-bar.txt
lrwxrwxrwx 1 me 19 28 fév 12:04 c.txt -> ../../ref/c-baz.txt

使用cp -a reorg/*.txt reorg/subdirmv reorg/*.txt reorg/subdir将产生一堆断开的符号链接,因为它们将丢失多余的../。而且由于这些符号链接中编码的重组量很大,因此从头开始重新创建符号链接将需要进行大量工作。

有人知道像rename这样的解决方案,但是会系统地改变我的数千个符号链接目标吗?

显而易见的解决方案(可能是我会做的)是编写一个bash脚本,如下所示:

mv reorg/*.txt reorg/subdir
for l in reorg/subdir/*.txt; do
   newtarget=`readlink $l | sed 's/^/..\//'`
   ln -sf $newtarget $l
done

并且该方法有效,我进行了测试,但是我希望找到一个更直接的解决方案,类似于rename,所以我每次遇到问题时都不必编写这样的脚本。我经常使用符号链接,所以这个问题会再次出现。

如果存在的话(这是我的理想解决方案)(使用CentOS类似于重命名的语法,而不是Ubuntu的语法,但是两者都很好):

mv reorg/*.txt reorg/subdir
rename-link-targets ../ ../../ reorg/subdir/*.txt

1 个答案:

答案 0 :(得分:1)

TL; DR :不,我不知道您所描述的符号链接编辑器。

现在,有一个骇客:

cd reorg
ln -s ../ref .

我知道您不需要每次都重新执行for循环,但是您的for循环来编辑数千个链接也可能是for循环来重新创建数千个链接,不是吗?

rm -rf reorg
mkdir reorg/subdir
cd reorg/subdir
for f in ../../ref/*.txt; do
   ln -s $f .
done
cd ../..

最后,重点关注“每次遇到此问题时”部分,请考虑在符号链接中使用绝对路径。然后,您可以将reorg / subdir移至所需的任何位置,并且路径仍然有效:

rm -rf reorg
mkdir reorg/subdir
cd reorg/subdir
for f in /absolute/path/to/ref/*.txt; do
   ln -s $f .
done
cd ../..

如果仍然无法解决问题,我将返回hack:

  • 将文本文件保存在已知目录(参考)中
  • 创建/ path / to / sym-dir,它是指向该目录的符号链接(参考)
  • 在reorg / subdir中创建符号链接,这些符号链接链接到/ path / to / sym-dir中的特定文件

现在,您可以将reorg / subdir移至所需的任何位置,因为这些符号链接使用绝对路径。而且,您可以将ref移到您想要的任何位置,只要 吹走/ path / to / sym-dir并重新创建它。

当然,fopen会因为必须经历两个间接级别而对您发牢骚,但这可能是必须付出的代价。

HTH。