Qual é a melhor maneira de usar a expansão curinga no bash quando a origem e o destino são semelhantes?

Qual é a melhor maneira de usar a expansão curinga no bash quando a origem e o destino são semelhantes?

Suponha que eu tenha estas pastas:

$ ls
css-tricks/ django-tutorial/ good-tuts.txt js-tut/ tutorials/ tuts.txt

Alguns deles têm tutem seus nomes. Gostaria de mover todos os arquivos/pastas que possuem tutseus nomes para a pasta tutorials/. Se eu executar o comando

$ mv *tut* tutorials/

Recebo a seguinte mensagem:

mv: cannot move 'tutorials' to a subdirectory of itself, 'tutorials/tutorials'

O que posso fazer para evitar tal cenário?


Um dos truques que consigo pensar é renomear temporariamente a pasta de destino para outra coisa e, após a execução do comando, alterá-la novamente para o nome desejado. No entanto, espero conhecer uma solução mais elegante para o problema.

Responder1

Pessoalmente, em uma situação em que estou prestes a dar o comando de forma interativa, eu simplesmente faria mv *tut* tutorialse esperaria receber o erro "não é possível mover". É inofensivo e os outros arquivos e diretórios terão sido movidos conforme o esperado.

O status de saída do comando será diferente de zero, sinalizando um erro, mas como nada depende disso, poderá ser ignorado.


Neste caso, os demais nomes contém um travessão antes tut:

mv *-tut* tutorials

Ou, se você também tem coisas assim python_tutque deseja mover, permita também um sublinhado:

mv *[_-]tut* tutorials

Ou, para exigir qualquer caractere extra antes da substring tut(que tutorialsnão possui),

mv *?tut* tutorials

Com um pouco mais de digitação e reflexão, usando um padrão globbing estendido em bash:

shopt -s extglob
mv *tut!(orials*) tutorials

Esta segunda variação corresponderá a qualquer coisa que contenha a substring tutnão seguida imediatamente pela string orials. O padrão não corresponderia tutorialse também pularia tutorials1etc.

Responder2

Você também pode usar find:

find . -type d -name "*tut*" -not -path "./tutorials" -exec mv -t "tutorials" {} +

Responder3

Recebo a seguinte mensagem:

mv: cannot move 'tutorials' to a subdirectory of itself, 'tutorials/tutorials'

Apenas ignore o erro.

Não mesmo. Você sabe que receberá o erro, pois o padrão glob corresponde ao destino. Você também sabe que isso não significa nada, já que o sistema não pode mover o diretório dentro de si e é inteligente o suficiente para perceber isso antes de bagunçar seu sistema de arquivos.

Responder4

A maneira mais fácil é renomear o diretório de destino tutorials/para algo que não corresponda na expansão do nome do arquivo e renomeá-lo conforme desejar após realizar a movimentação.

informação relacionada