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 / unix / Perguntas / 556545
Accepted
hippietrail
hippietrail
Asked: 2019-12-11 07:03:31 +0800 CST2019-12-11 07:03:31 +0800 CST 2019-12-11 07:03:31 +0800 CST

Bash globbing que corresponde a todos os arquivos, exceto aqueles com uma extensão específica, que funciona em nomes de arquivos que incluem caracteres de ponto

  • 772

Estou fazendo algumas coisas com arquivos de áudio, a maioria, mas não todos, são arquivos mp3. Agora eu quero executar alguns comandos apenas nos arquivos que não são arquivos mp3, ou apenas naqueles que não possuem .mp3extensão.

Eu me considero muito bom em expressões regulares, mas não tanto em globbing de arquivos, que é sutilmente diferente de maneiras inesperadas.

Olhei em volta e aprendi com outras respostas SO & SE que Bash tem "globbing estendido" que me permite fazer isso:

file ../foo/bar/*.!(mp3)

Mas alguns dos meus nomes de arquivo têm pontos além do que forma a extensão do nome do arquivo:

../foo/bar/Naked_Scientists_Show_19.10.15.mp3
../foo/bar/YWCS_ep504-111519-pt1_5ej4_41cc9320.mp3_42827d48daefaa81ec09202e67fa8461_24419113.mp3
../foo/bar/eLife_Podcast_19.09.26.mp3
../foo/bar/gdn.sci.080428.bg.science_weekly.mp3

Parece que o glob combina do primeiro ponto em diante, e não do último ponto. Eu olhei para a documentação, mas parece que eles são muito menos poderosos que os regexes. Mas eu realmente não groguei tudo, pois não gasto muito tempo em *nix shells.

Eu perdi alguma maneira de ainda poder fazer isso com o Bash globbing? Se não, uma maneira de conseguir a mesma coisa com find ou alguma outra ferramenta ainda valeria a pena conhecer.

bash filenames
  • 4 4 respostas
  • 8070 Views

4 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2019-12-11T07:09:09+08:002019-12-11T07:09:09+08:00

    *.!(mp3)corresponde foo.bar.mp3porque é foo.seguido por bar.mp3que nãomp3 é .

    Você quer !(*.mp3)aqui, que corresponde a qualquer coisa que não termine em .mp3.

    Se você deseja corresponder arquivos cujo nome contém pelo menos um .(diferente de um inicial que os tornaria um arquivo oculto), mas não termina em .mp3, você pode fazer !(*.mp3|!(*.*)).

    • 22
  2. muru
    2019-12-11T17:44:14+08:002019-12-11T17:44:14+08:00

    Há também a GLOBIGNOREvariável :

    A GLOBIGNOREvariável shell pode ser usada para restringir o conjunto de nomes de arquivos que correspondem a um padrão. Se GLOBIGNOREestiver definido, cada nome de arquivo correspondente que também corresponder a um dos padrões em GLOBIGNOREserá removido da lista de correspondências. Se a nocaseglobopção estiver definida, a correspondência com os padrões em GLOBIGNOREserá executada sem considerar maiúsculas e minúsculas. Os nomes dos arquivos .e ..são sempre ignorados quando GLOBIGNOREsão definidos e não são nulos. No entanto, definir GLOBIGNOREum valor não nulo tem o efeito de habilitar a dotglobopção shell, portanto, todos os outros nomes de arquivo que começam com ' .' serão correspondentes. Para obter o comportamento antigo de ignorar nomes de arquivos começando com ' .', faça ' .*' um dos padrões em GLOBIGNORE. odotglobopção é desabilitada quando GLOBIGNOREnão está configurada.

    $ touch a.b.mp3 .c.mp3 foo.tgz .bar
    $ echo *
    a.b.mp3 foo.tgz
    $ shopt -s extglob; echo *.!(mp3)
    a.b.mp3 foo.tgz
    $ GLOBIGNORE='*.mp3'; echo *
    .bar foo.tgz
    
    • 6
  3. Kramer
    2019-12-11T07:15:32+08:002019-12-11T07:15:32+08:00

    a maneira mais simples que consigo pensar:

    find ${path-to-folder} -type f  | grep -vE ".*\.mp3$"
    

    Você encontra todos os arquivos em uma pasta e os canaliza para um grep estendido reverso:

    Encontre todos os arquivos em um local

    find ${path-to-folder} -type f 
    

    Reverse grep e use um regex para filtrar por extensão

    grep -vE ".*\.mp3$"
    

    Sinalizadores de Grep:

    • -vgrep reverso

    • -Egrep estendido (uso de regex)

    Regex explicou:

    • .*significa de 0 a qualquer contagem de caracteres, qualquer caractere possível

    • \.procura o ponto real

    • mp3para a string que forma a extensão

    • $significa EOL

    • 2
  4. Rakib Fiha
    2019-12-11T07:44:35+08:002019-12-11T07:44:35+08:00

    Possivelmente não é o ideal para sua situação, mas eu queria saber que tal fazer uma função em puro Bashe depois passar a extensão como um arg, o que pode ser útil se você quiser adicioná-lo no seu bashrce quiser fazer a mesma coisa no futuro, como o seguinte

    Então, basicamente o que estamos fazendo é a verificação de regex para a extensão desejada.

    for file in *; do
      if [[ $file =~ \.mp3$ ]]; then
        echo $file
      fi
    done
    

    Implementando-o em uma função: Isso produziria todos os arquivos com extensão específica em seu diretório atual.

    getFileByExt(){
    local extension="$1"
    if (( $# == 1 )); then
    for file in *; do
      if [[ $file =~ \.$extension$ ]]; then
        echo $file
      fi
    done
    else
      echo "Usage: ${FUNCNAME[0]} <extension>" 
    ## If run from bashrc, return the name of function
    fi
    }
    

    Agora, por exemplo, para obter todos os arquivos com mp3extensão, seria tão simples quanto fazer:

    getFileByExt mp3
    

    E para obter arquivos sem extensão específica: Isso produziria todos os arquivos que não possuem extensão específica em seu diretório atual.

    getFileWithoutExt(){
    local extension="$1"
    if (( $# == 1 )); then
    for file in *; do
      if [[ ! $file =~ \.$extension$ ]]; then
        echo $file
      fi
    done
    else
      echo "Usage: ${FUNCNAME[0]} <extension>"
    fi
    }
    

    Da mesma forma, para obter arquivos sem mp3extensão, basta fazer:

    getFileWithoutExt mp3
    

    Para mais informações:

    https://stackoverflow.com/questions/407184/how-to-check-the-extension-of-a-filename-in-a-bash-script

    https://stackoverflow.com/questions/18278990/easiest-way-to-check-for-file-extension-in-bash/18280350

    • 1

relate perguntas

  • exportar variáveis ​​​​env programaticamente, via stdout do comando [duplicado]

  • Problema estranho ao passar variáveis ​​do arquivo de texto

  • Enquanto a linha lê mantendo os espaços de escape?

  • ordem de substituição de processos `te` e `bash`

  • Execute um script muito lento até que seja bem-sucedido

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

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