
以下は、対話する古いエラーシンボリックリンクを再配置する小さなスクリプトです。
#!/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
レイアウトは本物ではなく、通常は1行にする必要がありますdone
が、前のセミコロンは重複しません。
以下も使用できます。
right="${wrongpath/$oldtargetdir/$goodtargetdir}"
これにより、子プロセスのオーバーヘッドが防止されます。
答え2
変数は一重引用符で拡張されず、二重引用符で囲まれます。
また、これらの簡単な置き換えを実行するためにsedは必要なく、パラメータ拡張を使用できます。
right=${wrongpath/$oldtargetdir/$goodtargetdir}