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 / computer / Perguntas / 1869093
Accepted
Zsar
Zsar
Asked: 2025-01-04 00:33:28 +0800 CST2025-01-04 00:33:28 +0800 CST 2025-01-04 00:33:28 +0800 CST

Como o GNU Awk corresponde expressões com grupos de captura?

  • 772

Estou testando isso em um sistema Debian 10 bem antigo usando

GNU Awk 4.2.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.1.2)

em

GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)

Ambos os comandos awke gawkchamam esta mesma versão do GNU Awk.

Usando essas respostas [1] [2] [3] Estou tentando escrever um script que detecta conflitos de mesclagem gettext emitidos por msgcat.

Entrada de teste de texto simples, referida abaixo como merged_file.po:

"#-#-#-#-#  de.po (Application Library)  #-#-#-#-#\n"
"#-#-#-#-#  de.po (Middleware Library)  #-#-#-#-#\n"
"#-#-#-#-#  de.po  #-#-#-#-#\n"

Escolhi awk em vez de grep e sed para pular um cabeçalho usando NR > <line number>. Como isso funciona sem problemas, omito aqui por brevidade.

Sintaxe da linha:

  1. "#-#-#-#-#
  2. nome do arquivo de origem
  3. (Project-Id-Version) se definido no arquivo de origem
  4. #-#-#-#-#\n"

Expressão regular construída usando RegExr e validada em todos os sabores suportados pelo regex101 : #-#-#-#-#\s+\S+\s+(?:\(([^()]+)\)\s+)?#-#-#-#-#
(Observe que isso pressupõe que o nome do arquivo não contenha espaços em branco - por enquanto, não me importo.)

O efeito pretendido é duplo:

  1. encontre todas as ocorrências no arquivo .po de saída para emitir uma mensagem de erro
  2. capture o nome da biblioteca no grupo de captura 1 para tornar a mensagem de erro mais fácil de ler (especialmente para pessoas não muito familiarizadas com gettext)

Estas são as invocações que tentei:

  • A linha de base de trabalho awk '/#-#-#-#-#\s+\S+\s+(?:\(([^()]+)\)\s+)?/ { print NR, $0 }' merged_file.poencontra todas as ocorrências e imprime a linha inteira.
  • awk '/#-#-#-#-#\s+\S+\s+(?:\(([^()]+)\)\s+)?#/ { print NR, $0 }' merged_file.podescarta todas as ocorrências com Project-Id-Version
  • awk 'match($0, /#-#-#-#-#\s+\S+\s+(?:\(([^()]+)\)\s+)?/, library_name) { print NR, "from library \047"library_name[1]"\047" }' merged_file.poimprime a string vazia em vez de<Project-Id-Version>
    • library_name[0]contém a linha até o grupo não-capturador, então aparentemente matchnão emite grupos de captura - se emitisse, library_name[0]conteria a linha inteira.
  • awk '/#-#-#-#-#\s+\S+\s+(?:\(([^()]+)\)\s+)?/ { library_name = gensub(/#-#-#-#-#\s+\S+\s+(?:\(([^()]+)\)\s+)?/, "\\1", "g"); print NR, "from library \047"library_name"\047" }' merged_file.poimpressões "(<Project-Id-Version>) #-#-#-#-#\n"em vez de<Project-Id-Version>
    • \\0na verdade contém a linha inteira.
    • \\2contém a mesma string que \\1though. (esperado: vazio)

O suporte a RegEx em ferramentas relacionadas, como grep ou sed, costuma ser surpreendentemente vestigial, então, em vez de apenas perguntar por que minhas invocações específicas não funcionam, prefiro perguntar de forma mais geral:

Como a correspondência de expressões regulares do GNU Awks difere da "norma"?

Respostas X/Y (definitivamente) válidas:

  • Estou usando uma versão muito antiga. (Se sim: qual delas eu preciso no mínimo?)
  • Sou cego e meu RegEx está quebrado. (Se sim: como?)
  • A culpa é do Bash e eu preciso de algumas fugas arcanas. (Se sim: quais e por quê?)
  • Baeldung está errado desta vez e, afinal, há uma solução muito mais fácil que não seja usar Awk. (Se sim: qual?)
    • Para que eu não sofra o mesmo problema novamente no futuro, eu gostaria de receber este em adição a , não em vez de uma resposta à pergunta em si. Eu realmente gostaria de entender melhor o que posso esperar do Awk e o que não posso.
regex
  • 1 1 respostas
  • 59 Views

1 respostas

  • Voted
  1. Best Answer
    Zsar
    2025-01-14T00:35:06+08:002025-01-14T00:35:06+08:00

    Parece [ 1 ][ 2 ] que qualquer expressão que comece com um parêntesis sem escape - por exemplo, um grupo de captura - e continue com um ponto de interrogação - por exemplo, um grupo não capturador - é um comportamento indefinido em Expressões Regulares Estendidas Posix e gawk em particular achou por bem... ceder.

    Usando apenas grupos de captura normais, a expressão #-#-#-#-#\s+\S+\s+(\(([^()]+)\)\s+)?#-#-#-#-#corresponde conforme o esperado e match($0, <expression>, library_name)captura corretamente o grupo interno como library_name[2].

    ... O comportamento de gensubnão mudou significativamente, mesmo com a expressão bem definida, mas, desde que um dos comandos funcione, acho que está "bom o suficiente".
    (Sugestões sobre como fazer funcionar, bem-vindo para melhorar ainda mais a resposta.)


    Pediram-me para incluir a invocação e a saída resultantes, então aqui está (depois de contabilizar os caracteres de escape):

    CONFLICT_MARKER='#-#-#-#-#\s+\S+\s+(\(([^()]+)\)\s+)?#-#-#-#-#'
    METADATA_LINE_NUMBER=$(sed -n '/^$/{=;q}' "$PO")
    CONFLICTS=$(awk "NR > $METADATA_LINE_NUMBER && /$CONFLICT_MARKER/ && match(\$0, /$CONFLICT_MARKER/, library_name) { print NR, \"from library \047\"library_name[2]\"\047\" }" "$PO")
    if [ "$CONFLICTS" ]; then
        printf "Merge conflicts found in '%s':\n%s\n" "$PO" "$CONFLICTS"
        EXIT_STATUS=3
    fi
    

    (onde $POestá o nome do arquivo totalmente qualificado de saída do msgcat / passado para o msgfmt)

    Isso gera (mantendo a convenção de nomenclatura do OP)

    Merge conflicts found in '<full path>/merged_file.po':
    3785 from library 'Middleware Library'
    3790 from library 'Application Library'
    

    que parece agradável, informativo e nada ameaçador em um arquivo de log, comparado à saída de linha de base visualmente ocupada, mas nada mais útil

    Merge conflicts found in '<full path>/merged_file.po':
    3785 #-#-#-#-#  pt.po (Middleware Library)  #-#-#-#-#
    3790 #-#-#-#-#  pt.po (Application Library)  #-#-#-#-#
    
    • 0

relate perguntas

  • Substituir o terceiro valor

  • Como extrair nomes de arquivos vazios de uma lista de caminhos de arquivo usando regexes

  • Notepad ++ excluir até dois pontos para cada linha com substituir tudo

  • Existe um .gitignore para OneDrive?

  • Como parar de pesquisar se uma string ocorrer antes de outra string no Regex

Sidebar

Stats

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

    Como posso reduzir o consumo do processo `vmmem`?

    • 11 respostas
  • Marko Smith

    Baixar vídeo do Microsoft Stream

    • 4 respostas
  • Marko Smith

    O Google Chrome DevTools falhou ao analisar o SourceMap: chrome-extension

    • 6 respostas
  • Marko Smith

    O visualizador de fotos do Windows não pode ser executado porque não há memória suficiente?

    • 5 respostas
  • Marko Smith

    Como faço para ativar o WindowsXP agora que o suporte acabou?

    • 6 respostas
  • Marko Smith

    Área de trabalho remota congelando intermitentemente

    • 7 respostas
  • Marko Smith

    O que significa ter uma máscara de sub-rede /32?

    • 6 respostas
  • Marko Smith

    Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows?

    • 1 respostas
  • Marko Smith

    O VirtualBox falha ao iniciar com VERR_NEM_VM_CREATE_FAILED

    • 8 respostas
  • Marko Smith

    Os aplicativos não aparecem nas configurações de privacidade da câmera e do microfone no MacBook

    • 5 respostas
  • Martin Hope
    Vickel O Firefox não permite mais colar no WhatsApp web? 2023-08-18 05:04:35 +0800 CST
  • Martin Hope
    Saaru Lindestøkke Por que os arquivos tar.xz são 15x menores ao usar a biblioteca tar do Python em comparação com o tar do macOS? 2021-03-14 09:37:48 +0800 CST
  • Martin Hope
    CiaranWelsh Como posso reduzir o consumo do processo `vmmem`? 2020-06-10 02:06:58 +0800 CST
  • Martin Hope
    Jim Pesquisa do Windows 10 não está carregando, mostrando janela em branco 2020-02-06 03:28:26 +0800 CST
  • Martin Hope
    andre_ss6 Área de trabalho remota congelando intermitentemente 2019-09-11 12:56:40 +0800 CST
  • Martin Hope
    Riley Carney Por que colocar um ponto após o URL remove as informações de login? 2019-08-06 10:59:24 +0800 CST
  • Martin Hope
    zdimension Ponteiro do mouse movendo-se nas teclas de seta pressionadas no Windows? 2019-08-04 06:39:57 +0800 CST
  • Martin Hope
    jonsca Todos os meus complementos do Firefox foram desativados repentinamente, como posso reativá-los? 2019-05-04 17:58:52 +0800 CST
  • Martin Hope
    MCK É possível criar um código QR usando texto? 2019-04-02 06:32:14 +0800 CST
  • Martin Hope
    SoniEx2 Altere o nome da ramificação padrão do git init 2019-04-01 06:16:56 +0800 CST

Hot tag

windows-10 linux windows microsoft-excel networking ubuntu worksheet-function bash command-line hard-drive

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