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 / 562164
Accepted
TomRoche
TomRoche
Asked: 2020-01-15 21:43:34 +0800 CST2020-01-15 21:43:34 +0800 CST 2020-01-15 21:43:34 +0800 CST

nova década: como dizer algo como `find /path/ -name 'file.20{19,20}*'` (mas que funciona)

  • 772

resumo:

  1. Um determinado sistema tem muitos arquivos de texto com nomes ~= [type of file].[8-digit date].
  2. Para pesquisar esses arquivos, eu gosto (e quero manter) usando este idioma: find /path/ -name 'file.nnnn*' -print | xargs -e fgrep -nH -e 'text I seek'(onde nnnn== ano de 4 dígitos)
  3. ... e na última década também fiz findglob ao longo de anos comofind /path/ -name 'file.201[89]*' -print | xargs ...
  4. ... mas agora não posso fazer findglob em 2019 e 2020 comfind /path/ -name 'file.20{19,20}*' -print | xargs ...
  5. ... embora esse "globbing de chaves" (termo correto?) funcione bem com ls!

Existe uma maneira {concisa, elegante} de dizer findo que eu quero, sem fazer a pós- findlimpeza (ou seja, o que estou fazendo agora) à la

find /path/ -name 'file.*' -print | grep -e '\.2019\|\.2020' | xargs ...

? FWIW, prefiro uma solução que funcione com xargs.

detalhes:

Trabalho em um sistema com muitas convenções que me precedem há muito tempo e que não posso mudar. Uma delas é que tem muitos arquivos de texto com nomes ~= [type of file].[8-digit date], por exemplo, woohoo_log.20191230. Ao pesquisar nesses arquivos por algum texto, normalmente (como em, quase sempre) uso o find ... grepidioma (geralmente usando Emacs' M-x find-grep). (FWIW, este é um sistema Linux com

$ find --version
find (GNU findutils) 4.4.2
...
$ bash --version
GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)

e atualmente não tenho status para alterar qualquer um deles, se eu quisesse.) Muitas vezes, conheço o intervalo de anos do assunto em questão e, portanto, tentarei restringir o que findretorna (para acelerar o processamento), com (por exemplo)

find /path/ -type f -name 'file.nnnn*' -print | xargs -e fgrep -nH -e 'text I seek'

onde nnnn== ano de 4 dígitos. Este WFM, e eu gosto (e quero continuar) usando o idioma acima ... especialmente porque também posso usá-lo para pesquisar anos como

find /path/ -type f -name 'file.201[89]*' -print | xargs ...

Mas esta nova década parece estar quebrando esse idioma, e (para mim pelo menos) de forma mais estranha. (Eu não estava aqui quando a última década mudou.) Suponha que eu escolha um texto que sei que está em um arquivo de 2019 && um arquivo de 2020 (como em, posso abrir os arquivos e ver o texto). Se eu atualmente faço

find /path/ -name 'file.20{19,20}*' -print | xargs ...

greptermina inesperadamente/irritantemente with no matches found, porque

$ find /path/ -name 'file.20{19,20}*' -print | wc -l
0

Mas se eu fizer

find /path/ -type f -name 'file.*' -print | grep -e '\.2019\|\.2020' | xargs ...

grepretorna os resultados esperados. O que é bom, mas ... ummm ... isso é apenas feio, especialmente desde que este "glob de chaves" (por favor, corrija-me se este uso estiver incorreto ou obsoleto) funciona a partir de ls! Ou seja, isso me mostra os arquivos no intervalo de ano relevante (ou seja, 2019..2020)

ls -al /path/file.20{19,20}*

Por isso gostaria de saber:

  1. Não estou dando findo glob certo para este caso de uso? O que eu preciso dizer findpara fazê-lo fazer o que lsestá fazendo corretamente/capazmente?
  2. Isso é um problema com xargs? Se sim, posso viver com uma find ... -execsolução, mas... meu cérebro funciona melhor com xargso , então prefiro ficar com isso se possível. (Me chame de débil mental, mas -execa sintaxe de faz meu cérebro doer .)
find wildcards
  • 3 3 respostas
  • 774 Views

3 respostas

  • Voted
  1. Best Answer
    Stéphane Chazelas
    2020-01-15T23:10:16+08:002020-01-15T23:10:16+08:00

    Com zsh, você pode usar globbing recursivo e seu <x-y>operador glob que corresponde a intervalos de números decimais:

    grep -nHFe 'text I seek' /path/**/file.<2019-2020>*(D-.)
    

    (o (D)para também procurar em diretórios ocultos ( Dot) como findfaria; presumivelmente você pode omiti-los se não os quiser, e -.é restringir ao arquivo regular ( .) identificado após a resolução do link simbólico ( -)).

    Observe que também corresponderia file.00002020(já que é um número decimal entre 2019 e 2020) e, como em sua abordagem, file.20201234como file.2020quais correspondências file.<2019-2020>seguidas por 1234quais correspondências *.

    A maneira padrão (POSIX she utilitários) de fazer isso seria com:

    find /path \( -name 'file.2019*' -o -name 'file.2020*' \) -type f \
      -exec grep -Fne 'text I seek' /dev/null {} +
    

    (onde adicionar /dev/nullvocê obtém o mesmo efeito que GNU greppara -Hforçar o nome do arquivo a ser exibido)

    Observe que a saída de find -printnão é compatível com o formato de entrada esperado de xargs. Com os utilitários GNU, você pode usar find -print0e xargs -r0, mas isso não é necessário, pois find -exec ... {} +tem o mesmo comportamento, é mais curto e mais portátil.

    • 12
  2. muru
    2020-01-15T22:02:11+08:002020-01-15T22:02:11+08:00

    Em ls -al /path/file.20{19,20}*, não é isso lsque faz nada com {19,20}*. Nesse comando, o shell executa expansão de chaves e globbing , /path/file.20{19,20}*pois não é citado :

    bash-5.0$ set -x
    bash-5.0$ echo {a,b}
    + echo a b
    a b
    bash-5.0$ ls {a,b}
    + ls a b
    ls: cannot access 'a': No such file or directory
    ls: cannot access 'b': No such file or directory
    bash-5.0$ find -iname {a,b}
    + find -iname a b
    find: paths must precede expression: `b'
    

    Em find /path/ -name 'file.20{19,20}*', 'file.20{19,20}*'é citado, então o shell o deixa em paz e, findem seguida, aplica suas próprias regras de correspondência de padrões , que não suportam expansão de chaves. Aqui citando o manual GNUfind :

    Chaves dentro do padrão (' {}') não são consideradas especiais (ou seja, find . -name 'foo{1,2}'correspondem a um arquivo chamado foo{1,2}, não aos arquivos foo1e foo2.

    Se você realmente deseja usar a expansão de chaves para pesquisar recursivamente um diretório, no bash, você pode habilitar o globbing recursivo ( globstar) (e possivelmente dotglobprocurar no diretório oculto como findfaria) e usar printfcom xargs:

    shopt -s globstar
    printf "%s\0" /path/**/file.20{19,20}* | xargs -0 ...
    

    Ou você pode usar findcom -regexem vez de -namecomo suportado por algumas findimplementações. Com GNU find:

    find  /path -regextype posix-extended -regex '.*/file.20(19|20)[^/]*'
    
    • 6
  3. Drew
    2020-01-16T10:46:39+08:002020-01-16T10:46:39+08:00

    Não é uma resposta geral para sua pergunta, mas pode haver uma maneira fácil de fazer isso, dependendo da quantidade de histórico de arquivos que você possui. Muitas vezes me deparei com uma situação semelhante com meses ao procurar coisas em setembro / outubro. Uma solução fácil é usar o padrão a como este:

    file.20[12][90]*
    

    Não é idêntico, porque, além de 2019 e 2020, também corresponderá a 2010 e 2029. Presumivelmente, você ainda não tem nenhum arquivo datado de 2029. Se seu arquivo não remonta a 2010, isso deve ser funcionalmente equivalente.

    • 0

relate perguntas

  • Imprima variáveis ​​do subshell para o shell pai [duplicado]

  • verificando se existe uma pasta em determinado diretório

  • Localizar e substituir cores em arquivos CSS na linha de comando

  • GNU find: obtenha caminho absoluto e relativo em -exec

  • mv *.cache.{js,woff} sub_pasta - funciona como comando shell, mas não dentro de um Makefile

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