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.