-
Você pode usar os padrões avançados de globbing em alguns shells para corresponder a todos os arquivos em um diretório, exceto aqueles que correspondam 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 em
/source
para/destination
, exceto os arquivos que correspondem a*.bak
. Em zsh, você também pode escrever/source/^*.bak
se primeiro executarsetopt extended_glob
e, mais geralmente (novamente, exigindosetopt extended_glob
)/source/*~*.bak
(ou/source/a*~*.bak
para todos os arquivos cujo nome comece coma
, exceto.bak
de arquivos, etc). -
Zsh tem 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
paratarget
, e adiciona.bak
ao nome deles 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 arquivos para um novo nome gerado por uma expressão perl. Você pode excluir arquivos de renomeação, não gerando um novo nome se o arquivo for excluído. Por exemplo, o comando a seguir (usando esse programarename
específico) move todos os arquivos, exceto*.bak
de/source
para/target
:rename 's!/source!/target! unless m!\.bak$!' /source/*
-
Você pode usar o comando
find
para selecionar os arquivos que deseja mover. Por exemplo, o comando a seguir move todos os arquivos regulares, exceto*.bak
in/source
ou um subdiretório para/target
(observe que a estrutura de diretórios está recolhida):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 decp
escp
com regras de inclusão / exclusão muito poderosas. Por exemplo, o comando a seguir copia todos os arquivos, exceto*.bak
in/source
ou um subdiretório em/target
, respeitando a estrutura de diretório:rsync -a --exclude '*.bak' /source/ /target/
-
pax
é (entre outras coisas) outrocp
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 os arquivos à medida que são copiados. Se você renomear um arquivo para a string vazia, ele será excluído da cópia. Por exemplo, o comando a seguir copia todos os arquivos, exceto*.bak
in/source
ou um subdiretório para/target
, e renomeia os arquivos para.bak
de passagem.cd /source && pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' . /target/
O exemplo acima tem o infeliz efeito colateral de criar diretórios chamados
foo.bak
, que podem ser evitados combinandofind
compax
:{ cd /source && find . -type f; } | \ pax -rw -pp -s '/.*\.bak$//' -s '/$/.bak/' /target/