Como posso mover todos os arquivos .jpeg não ocultos usando caracteres de expansão do shell?

-11

Aqui está o meu problema:

Move all non-hidden files with names ending with .jpg (regardless of case - .jpg, .JPG, .JpG etc.) from your present working directory into /tmp.

Use shell expansion characters to accomplish this.

As expressões da shell não são minhas, pergunto-me como posso fazer isso. Sugestões?

    
por raven2313 30.03.2015 / 03:18

2 respostas

3

Você pode usar um padrão de shell com as classes de caracteres [ ] .

Para mover cada arquivo (e pasta)

  • que está localizado diretamente no diretório de trabalho atual, e
  • cujo nome não começa com . (ou seja, o arquivo não está oculto), e
  • cujo nome termina com .jpg ou uma de suas outras sete variantes de caso (como .JPG ou .Jpg )

para /tmp , você pode usar o comando:

mv -- *.[Jj][Pp][Gg] /tmp
  • Isso usa classes de caracteres para corresponder aos arquivos cujos nomes terminam em . e, em seguida, J ou j , em seguida, P ou p e, em seguida, G ou g . As classes de caracteres (com [ ] ) usam uma sintaxe mais compacta do que as expressões de chave ( { } ) e também têm o benefício de apenas expandirem para nomes de arquivos que realmente existem, portanto você não obterá mensagens de erro, mesmo que algumas variantes de .jpg não apareçam no final de nenhum nome de arquivo. (Você ainda verá uma mensagem de erro se os arquivos no forem correspondidos.)
  • Quando o shell expande os padrões, exclui os arquivos que começam com . por padrão, então nada de especial precisa ser feito para conseguir isso.
  • A opção -- garante que mv interprete tudo depois dela como um nome de arquivo e não como uma opção. Assim, mesmo se o padrão corresponder aos arquivos cujos nomes começam com - , eles serão tratados como nomes de arquivos literais e não opções para mv . (Isso poderia alternativamente ter sido alcançado prefixando o padrão com ./ , ou seja, mv ./*.[Jj][Pp][Gg] /tmp .)

Você pode ativar a opção nocaseglob shell e fornecer um padrão simples.

Uma maneira alternativa é ativar o nocaseglob opção de shell , que faz com que os padrões de nome de arquivo sejam correspondidos sem distinção entre maiúsculas e minúsculas. Como você provavelmente não precisa alterar essa configuração para comandos subseqüentes, é possível colocar os comandos que ativam nocaseglob e mover os arquivos entre parênteses para que eles executado em um subshell , para que o ambiente de chamada seja não afetado:

(shopt -s nocaseglob; mv -- *.jpg /tmp)

Como jpg tem apenas três caracteres, você pode preferir o método acima com as classes de caracteres. No entanto, para a globalização de palavras mais longas com distinção entre maiúsculas e minúsculas, torna-se bastante prático definir nocaseglob .

O que acontece se já houver arquivos com o mesmo nome em /tmp ?

No entanto, você decide especificar o padrão de arquivos a serem movidos, se um arquivo com o mesmo nome de um dos arquivos que estão sendo movidos já existir em /tmp , então o comportamento padrão de mv será seguido, como Nós não demos a mv nenhuma opção sobre como lidar com uma colisão. Isso é para dizer:

  • Se o arquivo de destino pré-existente tiver permissões de gravação para o usuário que está executando mv , ele será substituído de maneira automática e silenciosa pelo arquivo de origem.
  • Se o arquivo de destino pré-existente não tiver permissões de gravação para o usuário executando mv , mv solicitará ao usuário e perguntará o que fazer. (Sobrescrever o arquivo pode ainda ter sucesso nesse caso, se o usuário possuir o arquivo de destino pré-existente.)

Para especificar um comportamento diferente quando o arquivo de destino já existe, você pode usar as opções --backup , -b , -f , -i , -n ou -u , conforme documentado em:

por Eliah Kagan 02.05.2015 / 00:31
0

Simples:

mv ./*.{j,J}{p,P}{g,G} /path/to/folder/

ou alternativamente

mv "$(pwd)"/*.{j,J}{p,P}{g,G} /path/to/folder/
    
por Sergiy Kolodyazhnyy 01.05.2015 / 22:19