Você pode usar os padrões de globbing avançados em algumas shells para corresponder a todos os arquivos em um diretório, exceto aqueles que correspondem a um padrão específico. Por exemplo, em ksh, bash ou zsh, o comando
shopt -s extglob ## needed in bash only
setopt ksh_glob ## needed in zsh only
mv /source/!(*.bak) /destination
moverá todos os arquivos /source
para, /destination
exceto os arquivos correspondentes *.bak
. No zsh, você também pode escrever /source/^*.bak
se executar pela primeira vez setopt extended_glob
e de maneira mais geral (novamente exigindo setopt extended_glob
) /source/*~*.bak
(ou /source/a*~*.bak
para todos os arquivos cujo nome começa com a
exceção de .bak
arquivos, etc.).
O Zsh possui um comando de copiar / mover / link em massa que pode ser usado, entre outros, para mover todos os arquivos, exceto aqueles que correspondem a um padrão. Por exemplo, o comando a seguir move todos os arquivos, exceto *.bak
de /source
para target
, e adiciona .bak
seu nome no processo:
autoload zmv
zmv '/source/(*)~*.bak' '/target/$1.bak'
Existem vários comandos chamados rename
flutuando. No Debian e no Ubuntu, /usr/bin/rename
é um script perl que move os arquivos para um novo nome gerado por uma expressão perl. Você pode excluir os arquivos da renomeação não gerando um novo nome se o arquivo tiver que ser excluído. Por exemplo, o comando a seguir (usando este rename
programa específico ) move todos os arquivos, exceto *.bak
de /source
para /target
:
rename 's!/source!/target! unless m!\.bak$!' /source/*
Você pode usar o find
comando para selecionar os arquivos que deseja mover. Por exemplo, o seguinte comando move todos os arquivos regulares, exceto *.bak
em /source
ou em um subdiretório em /target
(note que a estrutura de diretórios é recolhido):
find /source -type f \! -name '*.bak' -exec mv {} /target/ \;
ou (mais eficiente se houver muitos arquivos para mover)
find /source -type f \! -name '*.bak' -exec sh -c 'mv "$@" "$0"' /target/ {} +
rsync
é uma generalização cp
e scp
com regras de inclusão / exclusão muito poderosas. Por exemplo, o comando a seguir copia todos os arquivos, exceto *.bak
em /source
ou em um subdiretório /target
, respeitando a estrutura de diretórios:
rsync -a --exclude '*.bak' /source/ /target/
pax
é (entre outras coisas) outro cp
em esteróides. Suas regras de exclusão não são tão poderosas quanto as do rsync, mas tem a capacidade adicional de renomear arquivos à medida que são copiados. Se você renomear um arquivo para a sequência vazia, ele será excluído da cópia. Por exemplo, o comando a seguir copia todos os arquivos, exceto *.bak
em /source
ou em um subdiretório /target
, e renomeia os arquivos para .bak
de passagem.
cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
O exemplo acima tem o efeito colateral infeliz de criar diretórios chamados foo.bak
, que podem ser evitados combinando-se find
com pax
:
{ cd /source && find . -type f; } | \
pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/
mv file1 file2 /path/to/destination
não vai fazer o que você quer que ele faça