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 / coding / Perguntas / 78430333
Accepted
merlin2011
merlin2011
Asked: 2024-05-05 04:41:57 +0800 CST2024-05-05 04:41:57 +0800 CST 2024-05-05 04:41:57 +0800 CST

Qual é a maneira correta de usar um pipe regex em um separador de campo awk?

  • 772

Considere a sequência hello(world).

Eu queria usar uma awkinvocação para extrair arquivos world.

Esta foi minha primeira tentativa e a saída foi uma string vazia, sem erros.

echo 'hello(world)' | awk -F'(|)'  '{print $2}'

Minha segunda tentativa foi usar classes de caracteres, que produziram o comportamento esperado:

echo 'hello(world)' | awk -F'[()]' '{print $2}'

No entanto, dado que a documentação do awk afirma que o separador de campos pode ser uma expressão regular, eu esperava que a primeira tentativa funcionasse.

Aqui está minha versão awk:

$ awk --version
GNU Awk 5.0.1, API: 2.0 (GNU MPFR 4.0.2, GNU MP 6.2.0)
Copyright (C) 1989, 1991-2019 Free Software Foundation.

Por que a expressão (|)não alcança o resultado desejado?

awk
  • 3 3 respostas
  • 40 Views

3 respostas

  • Voted
  1. Best Answer
    Ed Morton
    2024-05-05T19:23:28+08:002024-05-05T19:23:28+08:00

    O regexp (|)significa o mesmo que |, the (e )apenas coloque-o em um grupo desnecessariamente. Os metachares de agrupamento (e )regexp são úteis para escrever regexps, como (a|b)cdizer, que cpodem ser precedidos por aou b, ou para casos em que você precisa de grupos de captura para referência posterior posteriormente, mas não aqui.

    Se você não deseja (ser )tratado como metachars regexp, então você precisa escapar da abertura (, e apenas da abertura (, porque o fechamento )é apenas um metachar regexp se seguir uma abertura sem escape (, assim como ]é apenas um metachar regexp se for segue uma abertura sem escape [. Se você optar por escapar também do )comportamento ]tecnicamente indefinido por POSIX, assim como escapar de qualquer outro caractere literal, embora eu nunca tenha encontrado pessoalmente uma variante awk que não o tratasse apenas como um caractere literal.

    Assim como quando você escreve um regexp dinâmico , quando você escreve uma string Field Separator, ela passa por 2 fases de análise, primeiro quando a string é convertida em um regexp/separador de campo onde você a define, e novamente quando é usada como tal durante execução do código. Dado que, se você quiser \escapar dos metachares em um FS, você precisa escapá-los duas vezes, ou seja \\, . Alternativamente, em vez de colocar 2 barras invertidas antes do metachar, você poderia colocá-lo dentro de uma expressão de colchetes [...]e isso também o tornaria literal. A IMO faz o último torna seu código mais claro do que duplicar escapes e [)]não tem o pequeno problema que \\)é um comportamento tecnicamente indefinido se você decidir "escapar" de ambos os caracteres.

    Então, para fazer (e )literal você pode escrever qualquer um destes em qualquer awk:

    1. awk -F'\\(|)' '{print $2}'
    2. awk -F'[(]|)' '{print $2}'
    3. awk -F'[()]' '{print $2}'

    com minha preferência FWIW sendo o número 3, mesmo que )seja literal dentro ou fora da expressão entre colchetes, pois é mais conciso que as 2 primeiras alternativas.

    • 3
  2. merlin2011
    2024-05-05T04:41:57+08:002024-05-05T04:41:57+08:00

    Depois de brincar com a apresentação \de vários personagens, finalmente percebi que o problema era com o personagem ()e não com o |personagem. Além disso, era ()necessário escapar duas vezes.

    A seguinte expressão alcança o resultado desejado:

    echo 'hello(world)' | awk -F'\\(|\\)'  '{print $2}'
    world
    

    Curiosamente, omitir o escape no parêntese de fechamento também parece funcionar corretamente:

    echo 'hello(world)' | awk -F'\\(|)'  '{print $2}'
    world
    
    • 0
  3. Daweo
    2024-05-05T17:21:54+08:002024-05-05T17:21:54+08:00

    Por que a expressão (|)não alcança o resultado desejado?

    Dos operadores Regexp emawk

    O parêntese esquerdo ou de abertura é sempre um metacaractere; para corresponder a um literalmente, preceda-o com uma barra invertida. No entanto, o parêntese direito ou de fechamento só é especial quando combinado com um parêntese esquerdo; um parêntese direito não pareado é (silenciosamente) tratado como um caractere regular.

    levando isso em consideração, você pode obter o efeito desejado escrevendo

    echo 'hello(world)' | awk -F')|\\('  '{print $2}'
    
    • 0

relate perguntas

  • awk está imprimindo linhas duas vezes quando apenas um comando de impressão é usado

  • Analisando valores de coluna

  • Limitação de data do Gnuplot (2038?)

  • Comando Awk para obter linhas exclusivas em um arquivo com múltiplas colunas

  • Substitua a última metade de cada linha de um arquivo pela última metade da linha correspondente em outro arquivo [fechado]

Sidebar

Stats

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

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

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