Przenieś plik i zostaw miękki link za sobą


10

Szukam pojedynczego polecenia linux, które pozwoli mi zrobić równoważne z tym:

cp /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

Jeśli nie ma, jaki jest najlepszy sposób na zrobienie tego dla wielu plików?


Nie znam skryptów Bash wystarczająco dobrze, aby je napisać, ale moim rozwiązaniem byłoby po prostu napisanie skryptu i nazwanie go czymś chwytliwym jak cpln
Unkwntech

1
Czy CP nie powinien być mv?
Bart van Heukelom

Nie. Zajmuje się tym opcja -f dla ln.
innaM

1
wypróbuj go na pliku 10 GB
hayalci

2
@HelloGoodbye pan myli &&się &. Jak napisano, linia sprawdza wartość zwracaną cp i uruchamia drugą część, jeśli się powiedzie.
itsadok

Odpowiedzi:


7

Mała uwaga: możesz użyć ln dwa razy, aby polecenie faktycznie nie przenosiło danych (zakładając, że obie ścieżki znajdują się w tym samym systemie plików).

ln /some/path/file /another/path/ && ln -sf /another/path/file /some/path/

Zakładam jednak, że chcesz przenieść zawartość / some / path / na inny dysk, a następnie utworzyć łącza do nowych plików, aby nikt nie zauważył.

for f in `ls /some/path/`; do ln /some/path/$f /another/path/ && ln -sf /another/path/$f /some/path; done

Zawijanie go w funkcję bash:

function cpln {
    for f in `ls $1`
    do
        ln $1/$f $2 && ln -sf $2/$f $1
    done
}

Czy istnieje sposób, aby to zadziałało, jeśli to, co przenoszę, to katalog?
tladuke

Jak to przenosi rzeczywisty plik na dysk?
Ibrahim,

Ibrahim: dane się nie przenoszą, po prostu aktualizują wskaźniki w katalogu.
Pan Shark,

tladuke: Tak i nie. Ponieważ katalog jest znacznie mniejszy na dysku, sztuczka ln (która nie działa w przypadku katalogów) nie jest potrzebna, po prostu zrób mv :-)
Mr Shark,

2

Jest mój skrypt, którego możesz użyć (pobiera dwa parametry / some / path / file i / another / path /):

#!/bin/bash
cp $1 $2
if [ "$?" -ne "0" ]; then
    echo "Some error"
    exit 1
    fi
ln -sf $2/${1##*/} ${1%/*}

Fajna sztuczka z manipulacjami strunami, nigdy wcześniej tego nie widziałam. Dzięki!
itsadok

1

Poważnie, myślałem, że to było naprawdę łatwe pytanie.

Oto, co mogę zrobić w Perlu:

#!/bin/perl
# Usage: cpln TARGETDIR SOURCE...
# Example: find tree/ -type f | xargs cpln commands/

$target = shift;

foreach(@ARGV) {
    m[(.*)/([^/]+)];
    system("cp $_ $target");
    system("ln -sf $target/$2 $1/");
}

Miałem nadzieję na coś bardziej eleganckiego, ale chyba tego użyję.


1
Aby to zrobić „w Perlu”, należy użyć File :: Copy (lub podobnego) i symlink (). Perl nie jest powłoką; Unikaj system (), a zwłaszcza unikaj przekazywania całych linii poleceń do system () (np. co jeśli argument zawiera spację?). Tak czy inaczej, zawsze, zawsze ZAWSZE sprawdzaj zwracane wartości.
John Siracusa
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.