这是一个小脚本,用于重新定位我想要交互的旧错误符号链接。
#!/bin/bash
# retarget (broken) symbolink links interactively
echo -n "Enter the source directory where symlinks path should be retargeted > "
read response1
if [ -n "$response1" ]; then
symlinksdirectory=$response1
fi
if [ -d $symlinksdirectory ]; then
echo -n "Okay, source directory exists. Now enter 1) the symlinks OLD-WRONG target directory > "
read response2
if [ -n "$response2" ]; then
oldtargetdir=$response2
fi
echo -n "$oldtargetdir - And 2) enter the symlinks CORRECT target directory > "
read response3
if [ -n "$response3" ]; then
goodtargetdir=$response3
fi
echo -n "Now parsing symlinks in $symlinksdirectory to retarget them from $oldtargetdir to $goodtargetdir > "
find $symlinksdirectory -type l | while read nullsymlink ;
do wrongpath=$(readlink "$nullsymlink") ;
right=$(echo "$wrongpath" | sed s'|$oldtargetdir|$goodtargetdir|') ;
ln -fs "$right" "$nullsymlink" ; done
fi
它不会替换符号链接的路径。我的语法很糟糕,因为它在用真实路径替换变量时工作正常sed
(脚本结尾):
right=$(echo "$wrongpath" | sed s'|/mnt/docs/dir2|/mnt/docs/dir1/dir2|') ;
我应该如何正确插入变量?
答案1
您问题的直接答案是“使用双引号”,因为单引号会阻止所有扩展:
right=$(echo "$wrongpath" | sed "s|$oldtargetdir|$goodtargetdir|")
不需要尾随分号;仅当某些内容位于同一行时,它们才是必需的(因此前面的一个done
并不是多余的,尽管布局是非正统的,并且done
通常应该单独位于一行上)。
您还可以使用:
right="${wrongpath/$oldtargetdir/$goodtargetdir}"
这避免了子流程的开销。
答案2
变量不会用单引号展开,而是用双引号括起来。
此外,您不需要 sed 来进行如此简单的替换,您可以使用参数扩展:
right=${wrongpath/$oldtargetdir/$goodtargetdir}