Mover um arquivo e deixar um link para trás

10

Estou procurando um único comando linux que me permita fazer o equivalente a isso:

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

Se não houver, qual é a melhor maneira de fazer isso para vários arquivos?

itsadok
fonte
Eu não sei de script Bash bem o suficiente para escrevê-lo, mas a minha solução seria apenas para escrever um script e chamá-lo de algo cativante como cpln
Unkwntech
1
Cp não deve ser mv?
Bart van Heukelom
Não. A opção -f para ln cuida disso.
InnaM 14/05/09
1
experimentá-lo em um arquivo de 10GB
hayalci
2
@HelloGoodbye Você está confundindo &&com &. Conforme escrito, a linha verifica o valor de retorno de cp e somente executa a segunda parte se tiver êxito.
itsadok

Respostas:

7

Uma pequena observação é que você pode usar ln ambas as vezes para fazer com que o comando não mova os dados (assumindo que os dois caminhos estejam no mesmo sistema de arquivos).

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

Mas suponho que você queira mover o conteúdo de / some / path / para outro disco e crie links para os novos arquivos para que "ninguém" perceba.

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

Envolvendo-o em uma função bash:

function cpln {
    for f in `ls $1`
    do
        ln $1/$f $2 && ln -sf $2/$f $1
    done
}
Mr Shark
fonte
Existe uma maneira de fazer isso funcionar se o que eu estou movendo for um diretório?
tladuke
Como isso move o arquivo real no disco?
Ibrahim
Ibrahim: os dados não se movem, apenas atualizam os ponteiros no diretório.
Mr Shark
tladuke: Sim e não. Desde o diretório é muito smaler no disco, não há necessidade do truque ln (que não fazer o trabalho para directorys), basta fazer uma mv :-)
Sr. Tubarão
2

Existe o meu script que você pode usar (usa dois parâmetros / some / path / file e / outro / path /):

#!/bin/bash
cp $1 $2
if [ "$?" -ne "0" ]; then
    echo "Some error"
    exit 1
    fi
ln -sf $2/${1##*/} ${1%/*}
Kazimieras Aliulis
fonte
Truque legal com as manipulações de cordas, nunca vi isso antes. Obrigado!
Itsadok 17/05/09
1

Sério, pensei que essa era uma pergunta muito fácil.

Aqui está o que eu posso fazer em 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/");
}

Eu esperava algo mais elegante, mas acho que vou usar isso.

itsadok
fonte
1
Para fazer isso "no Perl", você deve usar File :: Copy (ou similar) e symlink (). Perl não é shell; evitar system (), e especialmente evitar passar linhas de comando inteiras para system () (por exemplo, que se um argumento contém um espaço?). De qualquer forma, sempre, sempre, SEMPRE verifique os valores de retorno.
3126 John Siracusa