Bir dosyayı taşıyın ve bir symlink ile değiştirin


16

Birisi bana şu komutu verebilir mi:

  • bir dosyayı yeni bir dizine taşıma
  • ve eski konumunda yeni bir noktaya bir sembolik bağlantı bırakın

Yanıtlar:


19

mvbir dosyayı taşır ve ln -ssembolik bir bağlantı oluşturur, böylece temel görev şu iki komutu yürüten bir komut dosyası tarafından gerçekleştirilir:

#!/bin/sh
mv -- "$1" "$2"
ln -s -- "$2" "$1"

Birkaç uyarı var. İkinci bağımsız değişken bir dizinse, mvdosyayı bu dizine taşır, ancak ln -staşınan dosya yerine dizine bir bağlantı oluşturur.

#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
  target="$target/${original##*/}"
fi
mv -- "$original" "$target"
ln -s -- "$target" "$original"

Diğer bir uyarı, ilk argümanın ln -ssembolik bağın tam metni olmasıdır. Komutun yürütüldüğü dizine değil, hedefin yerine bağlıdır. Orijinal konum geçerli dizinde değilse ve hedef mutlak bir yolla ifade edilmezse, bağlantı yanlış olur. Bu durumda, yolun yeniden yazılması gerekir. Bu durumda, mutlak bir bağlantı oluşturacağım (göreceli bir bağlantı tercih edilir, ancak doğru yapmak daha zordur). Bu komut dosyası, yeni satır karakteri ile biten dosya adlarınızın olmadığını varsayar.

#!/bin/sh
set -e
original="$1" target="$2"
if [ -d "$target" ]; then
  target="$target/${original##*/}"
fi
mv -- "$original" "$target"
case "$original" in
  */*)
    case "$target" in
      /*) :;;
      *) target="$(cd -- "$(dirname -- "$target")" && pwd)/${target##*/}"
    esac
esac
ln -s -- "$target" "$original"

Birden fazla dosyanız varsa, bunları bir döngüde işleyin.

#!/bin/sh
while [ $# -gt 1 ]; do
  eval "target=\${$#}"
  original="$1"
  if [ -d "$target" ]; then
    target="$target/${original##*/}"
  fi
  mv -- "$original" "$target"
  case "$original" in
    */*)
      case "$target" in
        /*) :;;
        *) target="$(cd -- "$(dirname -- "$target")" && pwd)/${target##*/}"
      esac
  esac
  ln -s -- "$target" "$original"
  shift
done

1
Senaryo ve açıklamalar için teşekkürler Gilles. Bunu anlamaya çalışacağım!
Yo

Bu doğru cevap olarak işaretlenmelidir
Sridhar Sarnobat

Bu yanıtı daha da harika hale getirmek için, rsync --remove-source-filesbüyük bir dosyayı bir diskten uzaklaştıran ve biraz zaman alabilen kullanıcılar için daha bilgilendirici olabilir.
Sridhar Sarnobat

Ben -e ile sh çağırmanız gerektiğini düşünüyorum, bu yüzden hatalar kesilir, örneğin bir dosya zaten var çünkü mv komutunu durdurursanız
Alex

2

Bunu .sh dosyasına koyun ve yürütülebilir ( chmod +x filename) yapın:

#!/bin/bash

mv "$1" "$2"
ln -s "$2" "$1"

Kullanım örneği:

./test.sh asdf otherdir/asdf

Bunun güvenlik kontrolü vb. Yapmadığını unutmayın. Görevinizin ne kadar karmaşık olduğuna bağlı olarak, bu yeterli olabilir.


Teşekkürler Matthew, bu bir dosyaya uygulandığında mükemmel çalışıyor. Ama beni böyle iki dizinlere bu generalising yardımcı olabilir: ./test.sh .mozila/firefox/zotero/*/*.pdf MyBbliography/*.pdf. *Parmağınızı ile çalışıyor gibi görünmüyor test.sh. Geçici bir çözüm var mı? Thx
Yo

2
@kadok MatthewRock'un komut dosyası yalnızca tek bir dosya için çalışır ve hedef mutlak bir yol olmalıdır, aksi takdirde kaynak geçerli dizinde olmalıdır.
Gilles 'SO- kötü olmayı kes

Ayrıca, $ 1 bir dosya, ancak 2 $ bir dizinse çalışmaz.
Sridhar Sarnobat

0

Genellikle bu tek satır işlevini kullanın:

function ml() { mkdir -p "$(dirname "$1")" && rsync -aP --no-links "$1" "$2" && ln -sf "$2" "$1" }

Kullanım mv veya cp'ye benzer:

ml old_file target_dir/new_file_name

Yıkmak:

  • mkdir -p "$(dirname "$1")" - henüz mevcut değilse hedef dizini oluşturun
    • dirname "$1" - yolun dizin bileşenini alın (dosya adını çıkarın)
  • rsync -aP --no-links "$1" "$2"- dosyayı hedefe kopyalayın. mv "$1" "$2"Daha iyi performans için her iki dosya da aynı dosya sistemindeyse bunu değiştirin .
    • -a- mülkiyeti ve diğer tüm izinleri korumak. Bunu yalnızca istediğiniz bileşenleri korumak için ayarlayabilirsiniz.
    • -P - ilerlemeyi göster.
    • --no-links - bağlantıları kopyalamayın - bu, bu komutu aynı dosyada istediğiniz kadar çalıştırabileceğiniz anlamına gelir ve hedef dosyanızı yanlışlıkla bir sembolik bağlantıyla üzerine yazarak dosyanızı hiçbir zaman kaybetmezsiniz.
  • ln -sf "$2" "$1" - eski dosyanın üzerine yeni bir link ekleyerek üzerine yaz
    • -s - sembolik bağlantılar kullanın
    • -f - eski dosyanın üzerine yaz
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.