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?


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
}

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%/*}

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.