Mover todos os arquivos, exceto um


155

Como posso mover todos os arquivos, exceto um? Estou procurando algo como:

'mv ~/Linux/Old/!Tux.png ~/Linux/New/'

onde movo coisas antigas para novas - pasta, exceto Tux.png. ! -sign representa uma negação. Existe alguma ferramenta para o trabalho?

Respostas:


142

Se você usa o bash e tem a extglobopção de shell definida (que geralmente é o caso):

mv ~/Linux/Old/!(Tux.png) ~/Linux/New/

1
Eu entendi algo errado quando testei o comando para muitos itens: mv ~ / Linux / Old /! (Tux.png Tux1.png Tux2.png) ~ / Linux / New / Esvazia todo o diretório antigo. O que está errado?
— Léo Léopold Hertz # 22/09

5
@UnixBasics, tente: ~ / Linux / Old /! (Tux.png | Tux1.png | Tux2.png)
— Juliano

@ Juliano Comando muito legal! Existem mais operações matemáticas como OR e XOR? Presumo que um pipe seja para AND.
— Léo Léopold Hertz # 22/09


@ Juliano Estou um pouco confuso com os padrões como: mv ~ / Linux /? (Tux * .png) ~ / Linux / Novo / mv ~ / Linux / + (Tux * .png) ~ / Linux / New / No primeiro , Eu queria mover 0-1 Tux -photo. Neste último, eu queria mover fotos 1-n Tux. Eles mudaram tudo. Por quê? É possível mover uma quantidade específica de fotos?
— Léo Léopold Hertz # 22/09

97

Coloque o seguinte em seu arquivo .bashrc

shopt -s extglob

Estende regexes. Você pode mover todos os arquivos, exceto um por

mv !(fileOne) ~/path/newFolder

Exceções em relação a outros comandos

Observe que, nos diretórios de cópia, o forward-flash não pode ser usado no nome conforme observado no encadeamento Por que extglob, exceto quebrar, exceto a condição? :

cp -r !(Backups.backupdb) /home/masi/Documents/

isso Backups.backupdb/está errado aqui antes da negação e eu não o usaria nem na movimentação de diretórios por causa do risco de usar incorretamente, depois globs com outros comandos e possíveis outras exceções.


3
Esta é realmente a resposta correta. O meu estava totalmente errado; felizmente eu o havia usado em uma pasta com apenas alguns arquivos. Aqui estão mais informações sobre o método que Masi mostra: wiki.bash-hackers.org/syntax/pattern Vá para "Linguagem de Padrão Estendido" e você encontrará mais informações sobre isso. Agradecemos a @ paul-whittaker por apontar o problema.
— mimoralea

Esta é uma resposta antiga, mas ainda é válida. Estou usando o Ubuntu 18 e o extglob parece estar ativado por padrão (não o comprei). Usei o seguinte comando para mover todos os arquivos no diretório atual para um arquivo que também esteja dentro deste diretório, NÃO incluindo outras pastas de arquivo: mv !(arc*) archive_190629b
— TonyG

70

Eu usaria a maneira tradicional do find & xargs:

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png -print0 | 
    xargs -0 mv -t ~/Linux/New

-maxdepth 1faz com que não procure recursivamente. Se você se importa apenas com arquivos, pode dizer -type f. -mindepth 1faz com que não inclua o ~/Linux/Oldpróprio caminho no resultado. Funciona com qualquer nome de arquivo, incluindo aqueles que contêm novas linhas incorporadas.

Um comentário observa que a -topção mv é provavelmente uma extensão GNU. Para sistemas que não possuem

find ~/Linux/Old -maxdepth 1 -mindepth 1 -not -name Tux.png \
    -exec mv '{}' ~/Linux/New \;

1
Voto a favor, pois incentiva o aprendizado de uma ferramenta poderosa, encontre. Observe que, para arquivos com espaço em branco, isso não funcionará. Considere "find -print0 | xargs -0" ou então renuncie ao xargs: "encontre [o que você disse] -exec mv -t {} ~ / Linux / New \;"
— 21477 JasonSmith

Se o seu comando mv não tiver a opção -t, use "find ... -exec mv {} Linux / New \;" ou "encontre ... | xargs -I {} mv {} Linux / Novo". A opção -t parece ser uma extensão GNU, o que é bom para Linux, mas provavelmente não em outro lugar.
— Rob Kennedy

jhs, oh eu falhei. De alguma forma, pensei que xargs se dividissem em novas linhas, mas não em espaços. Parece que eu confundido com "ler" :) doente corrigi-lo
— Johannes Schaub - litb

Muito obrigado pela dica incrível! Eu ia escolher sth porque ele tem como alvo a questão. No entanto, posso sentir a utilidade de seus comandos mais tarde, então devo escolher o modo "find and xargs". Apenas balança. Obrigado :)
— Léo Léopold Hertz 준영 26/03/09

Caminho para complicado. Masi resposta é mais completo, mais fácil e por isso mais correto
— user637338

30

Uma maneira rápida seria modificar o nome do arquivo tux para que seu comando de movimento não corresponda.

Por exemplo:

mv Tux.png .Tux.png

mv * ~/somefolder

mv .Tux.png Tux.png

não use " . ", pois isso moverá apenas arquivos com "." no nome. Apenas "*" é suficiente.
— Juliano

1
Se você alterá-lo para *, ele também removerá o arquivo renomeado.
— John T

6
@ John T: Não, o * glob não corresponde aos arquivos que começam com ponto.
— Bill Karwin

Esta é a melhor resposta de longe. Não há necessidade de alterar ou comentar esta resposta. 100 pontos. Muito obrigada. Bem feito!
— Steve K

23

Eu acho que a maneira mais fácil de fazer é com backticks

mv `ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Editar:

Use barra invertida com ls para evitar usá-lo com alias, ou seja, principalmente ls é alias como ls --color.

mv `\ls -1 ~/Linux/Old/ | grep -v Tux.png` ~/Linux/New/

Obrigado @Arnold Roa


1
Você pode explicar por que você usa grep -vlá?
— Léo Léopold Hertz # 23/16

1
A opção -v no grep exclui o resultado, é como pegar tudo, exceto o Tux.png
— Rohail Abbas

1
Isso certamente é intuitivo, mas as respostas acima são melhores. Se você estiver escrevendo um script, por exemplo, isso exigiria que você estivesse no diretório correto ..
— nJGL

@nJGL Nós também podemos dar um caminho absoluto aqui, eu usei o homedirectory (~) já que a pergunta tinha isso
— Rohail Abbas

@RohailAbbas Fair suficiente. ✌️
— nJGL 13/07

14

Para o bash, a resposta sth está correta. Aqui está a sintaxe zsh (meu shell de escolha):

mv ~/Linux/Old/^Tux.png ~/Linux/New/

Requer a EXTENDED_GLOBopção de shell a ser definida.


3
E se quisermos excluir dois arquivos?
— MPEN

13

Acho que isso é um pouco mais seguro e fácil de usar para movimentos simples que excluem determinados arquivos ou diretórios.

ls -1 | grep -v ^$EXCLUDE | xargs -I{} mv {} $TARGET

Esta é a melhor solução para o Busybox / ASH
— Stuart Cardall

1
Isso funcionou para mim na situação em que eu tinha que mover todos os arquivos, exceto algumas pastas para outra pasta
— Umar Hayat

A -lopção para lsincluir muitas informações irrelevantes na linha de comando e resultar em falha do comando mv.
— jdhao

5

O seguinte não é um método 100% garantido e não deve ser tentado de forma alguma para scripts. Mas algumas vezes é bom o suficiente para o uso rápido do shell interativo. Um arquivo de arquivo glob como

[abc]*

(que corresponderá a todos os arquivos com nomes começando com a, b ou c) pode ser negado inserindo-se primeiro um caractere "^", ou seja,

[^abc]*

Às vezes eu uso isso para não corresponder ao diretório "lost + found", como por exemplo:

mv /mnt/usbdisk/[^l]* /home/user/stuff/.

Claro que, se houver outros arquivos começando com l, tenho que processá-los posteriormente.


4
mv `find Linux/Old '!' -type d | fgrep -v Tux.png` Linux/New

O comando find lista todos os arquivos regulares e o comando fgrep filtra qualquer arquivo Tux.png. Os backticks dizem ao mv para mover a lista de arquivos resultante.


4
Nunca, jamais, avalie find como argumentos para outro comando. Coisas ruins vão acontecer. Você pode ter acabado de criar uma vulnerabilidade. Sempre use o comando find -print0 | xargs -0 construa ou encontre -exec.
— Juliano

3

Que tal mover tudo na pasta e depois mover o Tux.png de volta?

Não consigo pensar em nenhuma sintaxe do shell para dizer "tudo, exceto ..." de imediato.


3
ls ~/Linux/Old/ | grep -v Tux.png | xargs -i {} mv ~/Linux/New/'

1
Este comando parece estar faltando uma parte e não funciona no meu computador. ls ~/Linux/Old/ | grep -v Tux.png | xargs -I{} mv {} ~/Linux/New/funciona em vez disso.
— Katherine Chen

3

E se:

mv $(echo * | sed s:Tux.png::g) ~/Linux/New/

Você precisa estar na pasta.


3

Pode-se pular o grep assim:

ls ~/Linux/Old/ -QI Tux.png | xargs -I{} mv ~/Linux/Old/{} ~/Linux/New/

1

Isso poderia ser mais simples e fácil de lembrar e funciona para mim.

mv $(ls ~/folder | grep -v ~/folder/exclude.png) ~/destination

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.