Como encontrar um arquivo e movê-lo para o diretório em que ele foi encontrado

3

Estou tentando renomear arquivos em sub-diretórios usando xargs executando o seguinte comando:

find . -name oldfile.txt -print0 | xargs -n 1 -0 -I % mv % newfile.txt

O problema é que o arquivo é movido para o diretório em que eu executo o comando, em vez do diretório em que oldfile.txt é encontrado. Eu não consigo a solução para isso, alguma idéia?

Estou pensando que talvez eu possa obter o diretório do caminho do arquivo encontrado e, em seguida, anexá-lo à frente do segundo parador de mv , mas como isso funcionaria?

    
por Chris Bier 17.05.2013 / 21:08

1 resposta

3

Em vez de confiar em comandos externos, nos quais você perde as informações sobre o diretório atual, é possível usar find option para que seja executado comandos no diretório em que um arquivo foi encontrado.

find . -name oldfile.txt -execdir mv -- {} newfile.txt \;

Esta é na verdade uma versão mais segura de -execdir que é preferida na maioria das situações. O único inconveniente é que ele não é especificado pelo POSIX, então você não o encontrará em todas as variantes -exec - mas pelo menos no GNU find e no BSD find você pode.

Se você quiser ser mais seguro, chame find como mv para que um arquivo que comece com um traço não seja interpretado incorretamente como um argumento para mv -- source target .

Se por algum motivo você não quiser usar mv ou tiver outras coisas complicadas para fazer, ou apenas quiser aprender um pouco sobre o Bash, veja como obter a pasta e mover o arquivo com base nisso:

find . -name oldfile.txt -exec bash -c 'mv -- "${0}" "$(dirname $0)"/newfile.txt' {} \;

Aqui, -execdir passa o caminho completo para {} as bash . Obtemos o nome do diretório por meio da substituição de comando ( $0 ) e, em seguida, acrescentamos o novo nome. Tanto o argumento original quanto o nome do diretório precisam ser duplicados para evitar que o espaço em branco divida o comando - caso contrário, $(…) pensaria que você está tentando mover dois arquivos chamados mv e foo quando o arquivo é chamado de bar , por exemplo.

    
por 17.05.2013 / 21:22