Spostare un file e lasciare indietro un collegamento software


10

Sto cercando un singolo comando Linux che mi permetta di fare l'equivalente di questo:

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

Se non ce n'è uno, qual è il modo migliore per farlo per un mucchio di file?


Non conosco lo scripting Bash abbastanza bene per scriverlo, ma la mia soluzione sarebbe semplicemente scrivere uno script e chiamarlo qualcosa di accattivante come cpln
Unkwntech

1
Cp non dovrebbe essere mv?
Bart van Heukelom,

No. L'opzione -f per ln si occupa di questo.
InnaM

1
provalo su un file da 10 GB
hayalci,

2
@HelloGoodbye Ti stai confondendo &&con &. Come scritto, la riga verifica il valore di ritorno di cp e esegue la seconda parte solo se ha avuto successo.
iniziato

Risposte:


7

Una piccola nota è che è possibile utilizzare ln entrambe le volte per impedire al comando di spostare effettivamente i dati (supponendo che entrambi i percorsi si trovino sullo stesso filesystem).

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

Ma suppongo che tu voglia spostare il contenuto di / some / path / su un altro disco, e quindi creare collegamenti ai nuovi file in modo che "nessuno" se ne accorga.

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

Avvolgendolo in una funzione bash:

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

C'è un modo per farlo funzionare se quello che sto spostando è una directory?
Tladuke,

In che modo questo sposta il file effettivo sul disco?
Ibrahim,

Ibrahim: i dati non si spostano, aggiorna solo i puntatori nella directory.
Shark,

tladuke: Sì e no. Poiché la directory è molto più piccola su disco, non è necessario il trucco (che non funziona per le directory), basta fare un mv :-)
Mr Shark,

2

C'è il mio script che potresti usare (accetta due parametri / some / path / file e / another / path /):

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

Fantastico trucco con le manipolazioni delle stringhe, mai visto prima. Grazie!
iniziato

1

Seriamente, ho pensato che fosse una domanda davvero semplice.

Ecco cosa posso fare in perl:

#!/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/");
}

Speravo in qualcosa di più elegante, ma immagino che lo userò.


1
Per farlo "in Perl", dovresti usare File :: Copy (o simile) e symlink (). Perl non è shell; evitare system () e soprattutto evitare di passare intere righe di comando a system () (ad esempio, cosa succede se un argomento contiene uno spazio?). Ad ogni modo, sempre, sempre, controllare SEMPRE i valori di ritorno.
Giovanni Siracusa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.