シンボリックリンク新しいターゲット

シンボリックリンク新しいターゲット

現在のディレクトリを指すシンボリックリンクを/ poolというパブリックディレクトリに変更したいと思います。

現在のディレクトリa / bパブリックディレクトリa / pool

私は私が見つけることができるすべてに従い、このスクリプトで終わりました。

#!/bin/sh
from="$1"
to="$2"
shift 2
for i
do
  a=$(readlink "$i") && ln -sf "$(echo $a | sed "s@$from@$to@")" "$i"
done

スクリプトを実行する前に...

lrwxrwxrwx 1 neysa neysa  18 Jan  4 22:03 xfsm-logout.png -> system-log-out.png
lrwxrwxrwx 1 neysa neysa  17 Jan  4 22:03 zoom-best-fit.png -> zoom-fit-best.png

./rename-links スクリプトを実行した後。 ../スイミングプール/

lrwxrwxrwx 1 neysa neysa  25 Jan  4 22:31 xfsm-logout.png -> ../pool/ystem-log-out.png
lrwxrwxrwx 1 neysa neysa  24 Jan  4 22:31 zoom-best-fit.png -> ../pool/oom-fit-best.png

動作しますが、バグがあります。ターゲットの最初の文字がありません。私は何が間違っていましたか?

答え1

. 正規表現のメタ文字ですsed、これは任意の単一文字と一致します。これは、正規$from表現にパスを直接挿入するためです。.

sed "s@.@../pool/@"

あなた自身。それ変える一度に ""がある単一文字../pool/なので、最初の文字を削除してその場所に "../pool/"を挿入する効果があります。

コマンドを手動で実行すると、これがリンクの内容の一部ではないことreadlinkがわかります。ディスプレイは同じです。./ls

.リンクコンテンツに表示される場合と表示されない場合があるため、少なくともスクリプトで特別なケース「」を使用する必要があります。 1つのオプションは、次を使用することです。readlink -fon link と on .- これは両方の絶対パスを提供します。ただし、単一のケースのみを処理する必要がある場合は、より簡単なオプションがあります。


中にいれば完全にbash出かけてもいいsed基本パラメータ拡張の使用:

ln -sf "${a/$from/$to}" "$i"

これは$from拡張をinに置き換え、文字通り処理します(他の$to$a.*シェルメタ文字を使用してください。"${a/"$from"/"$to"}"実際には避けるべきです。全体的に、これはよりクリーンでシンプルなアプローチです。

関連情報