AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / ubuntu / Perguntas / 971082
Accepted
Alan
Alan
Asked: 2017-10-31 15:07:05 +0800 CST2017-10-31 15:07:05 +0800 CST 2017-10-31 15:07:05 +0800 CST

Renomeie os arquivos para serem capitalizados, mas sem afetar as extensões de arquivo

  • 772

Estou usando isso no diretório de um cliente para renomear arquivos com a primeira letra de cada palavra sendo maiúscula conforme sua solicitação:

rename 's/\b(\w)/\u$1/g' *

Isso funciona bem, mas também coloca em maiúscula a primeira letra da extensão, então eu uso isso para corrigir isso:

rename 's/\.Txt$/.txt/' *.Txt

o que funciona bem se a maioria dos arquivos em uma pasta tiver a mesma extensão (geralmente verdadeira), mas é uma dor se eles estiverem muito misturados.

Para contornar esse problema, criei um pequeno script parecido com este (não ria!):

#!/bin/bash
rename 's/\.Txt$/.txt/' *.Txt
rename 's/\.Doc$/.doc/' *.Doc
rename 's/\.Docx$/.docx/' *.Docx
...
rename 's/\.Xlsx$/.xlsx/' *.Xlsx

Eu ignoro os erros 'Não é possível renomear *.Txt *.txt: nenhum arquivo ou diretório' e, se encontrar uma extensão que está faltando, apenas adiciono essa linha ao meu script.

Acho que isso não importa, mas os arquivos estão em um compartilhamento de servidor Windows, mas estou acessando usando o Ubuntu 16.04LTS. Se isso importa, posso copiá-los para minha unidade local primeiro, executar um comando no Ubuntu e mover os arquivos de volta, se necessário.

Existe alguma maneira de alterar o primeiro comando renomear para ignorar as extensões e deixá-las em minúsculas? Posso executar o novo comando em um diretório de nível superior e fazer com que ele seja recursivo em todos os subdiretórios?

command-line
  • 4 4 respostas
  • 2714 Views

4 respostas

  • Voted
  1. Best Answer
    steeldriver
    2017-10-31T16:04:05+08:002017-10-31T16:04:05+08:00

    Uma forma de o conseguir poderá ser a utilização do Negative Lookbehind para corresponder apenas ao limite da palavra - sequência de caracteres da palavra quando não for precedida por um ponto literal, por exemplo, dado

    $ ls
    alan's file.txt  bar.txt  foo
    

    então

    $ rename -n 's/(?<!\.)\b\w*/\u$&/g' *
    rename(alan's file.txt, Alan'S File.txt)
    rename(bar.txt, Bar.txt)
    rename(foo, Foo)
    

    Supondo que você também queira evitar capitalizar o plural s, podemos modificar isso para

    $ rename -n 's/(?<![.'\''])\b\w*/\u$&/g' *
    rename(alan's file.txt, Alan's File.txt)
    rename(bar.txt, Bar.txt)
    rename(foo, Foo)
    

    ou mesmo

    $ rename -n 's/(?<![[:punct:]])\b\w*/\u$&/g' *
    rename(alan's file.txt, Alan's File.txt)
    rename(bar.txt, Bar.txt)
    rename(foo, Foo)
    
    • 7
  2. terdon
    2017-10-31T15:45:50+08:002017-10-31T15:45:50+08:00

    Isso colocará em maiúscula a primeira letra de cada palavra, exceto a extensão final:

    rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *
    

    Testei com esses arquivos:

    $ ls -1
    'a file with a '$'\n''new line.foo'
    'a file with spaces.txt'
    justonelongfilename.ext
    no-extensions-here
    this.has.many.extensions.pdf
    

    E ele irá renomeá-los como:

    $ rename -n 's/\b(.+?)\b/\u$1/g; s/(.+)\.(.)/$1\.\l$2/' *
    a file with a 
    new line.foo -> A File With A 
    New Line.foo
    a file with spaces.txt -> A File With Spaces.txt
    justonelongfilename.ext -> Justonelongfilename.ext
    no-extensions-here -> No-Extensions-Here
    this.has.many.extensions.pdf -> This.Has.Many.Extensions.pdf
    

    O truque é primeiro colocar todas as primeiras letras em maiúsculas, ignorando as extensões, e depois voltar e colocar a extensão em minúsculas:

    • s/\b(.+?)\b/\u$1/g;: O .+?é um padrão não ganancioso, o que significa que encontrará a correspondência mais curta possível. Uma vez que é ancorado por limites de palavras ( \b), ele encontrará todas as palavras (tudo por causa do final g). Estes são então substituídos pela versão em maiúscula (primeira letra maiúscula) de si mesmos ( \l$1).

    • s/(.+)\.(.)/$1\.\l$2/: o .+é ganancioso, por isso encontrará a correspondência mais longa possível. Isso significa a string mais longa até um final ., após o qual será a extensão (se houver). Substituímos a correspondência por tudo antes da extensão ( $1), a .e a extensão pela primeira letra minúscula novamente ( \l$2).


    A recursão também é bastante fácil. Se o seu shell for bash (se você não sabe, provavelmente é), você pode usar a opção globstar que faz **corresponder 0 ou mais subdiretórios:

    shopt -s globstar
    

    Agora, execute o comando renomear assim (isso também funcionará em qualquer arquivo em seu diretório atual):

    rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' **
    

    Para limitá-lo apenas a arquivos ou diretórios com extensões, use **/*.*em vez de **.

    Como alternativa, use find:

    find /path/to/dir -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +
    

    E, para limitar esses arquivos e diretórios com uma extensão:

    find /path/to/dir -name '*.*' -exec rename -n 's/\b(.+?)\b/\u$1/g; s/(.*)\.(.)/$1\.\l$2/' {} +
    

    Observe que todas essas soluções irão renomear alegremente diretórios, bem como arquivos . Se você não quiser isso, tenha cuidado onde você diz para recursar ou dê a ele um padrão mais específico como *.txt.


    Em todos os exemplos, remova o -n para fazê-los realmente fazer algo. As-ncausasrenamepara simplesmente imprimir o que faria e não fazer nada. Útil para testes.

    • 5
  3. Sergiy Kolodyazhnyy
    2017-10-31T15:15:55+08:002017-10-31T15:15:55+08:00

    A maneira mais sensata seria lidar com todas as "palavras" (com o uso do limite da palavra \be referindo-se $1a qualquer primeiro caractere), incluindo a extensão, mas, em seguida, diminua a própria extensão:

    $ prename -nv 's/\b(.)/\u$1/g;s/^(.*)\.(.*)/$1.\l$2/' *                                                                                                                
    another filename trispaced.txt renamed as Another Filename Trispaced.txt
    filename_with_underschore.txt renamed as Filename_with_underschore.txt
    one filename.txt renamed as One Filename.txt
    

    Observe que isso não funciona para nomes de arquivos com sublinhados, ou seja, limites de "palavras" são considerados em espaços em branco (tabulações, espaços, novas linhas - que esperamos que não devam estar no nome do arquivo de qualquer maneira).

    Observe o uso de prenamepara portabilidade para ksh, onde renamena verdade é um comando interno, não o perlexecutável autônomo.

    • 4
  4. V-Mark
    2017-10-31T15:12:35+08:002017-10-31T15:12:35+08:00

    Basta usar rename 's/\b(\w)/\u$1/' *SEM o sinalizador g.
    A bandeira g significa "global = faça várias vezes". Você faz a 1ª vez no nome do arquivo e não quer fazer letras maiúsculas na 2ª vez, certo?

    • 1

relate perguntas

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Existe um comando para listar todos os usuários? Também para adicionar, excluir, modificar usuários, no terminal?

    • 9 respostas
  • Marko Smith

    Como excluir um diretório não vazio no Terminal?

    • 4 respostas
  • Marko Smith

    Como descompactar um arquivo zip do Terminal?

    • 9 respostas
  • Marko Smith

    Como instalo um arquivo .deb por meio da linha de comando?

    • 11 respostas
  • Marko Smith

    Como instalo um arquivo .tar.gz (ou .tar.bz2)?

    • 14 respostas
  • Marko Smith

    Como listar todos os pacotes instalados

    • 24 respostas
  • Martin Hope
    Flimm Como posso usar o docker sem sudo? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    led-Zepp Como faço para salvar a saída do terminal em um arquivo? 2014-02-15 11:49:07 +0800 CST
  • Martin Hope
    ubuntu-nerd Como descompactar um arquivo zip do Terminal? 2011-12-11 20:37:54 +0800 CST
  • Martin Hope
    TheXed Como instalo um arquivo .deb por meio da linha de comando? 2011-05-07 09:40:28 +0800 CST
  • Martin Hope
    Ivan Como listar todos os pacotes instalados 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    David Barry Como determino o tamanho total de um diretório (pasta) na linha de comando? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher "Os seguintes pacotes foram retidos:" Por que e como resolvo isso? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford Como os PPAs podem ser removidos? 2010-07-30 01:09:42 +0800 CST

Hot tag

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve