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 / 78534641
Accepted
Fravadona
Fravadona
Asked: 2024-05-26 16:00:49 +0800 CST2024-05-26 16:00:49 +0800 CST 2024-05-26 16:00:49 +0800 CST

AWK equivalente a `read -r _ _ resto`

  • 772

Digamos que você tenha um arquivo que contém N colunas delimitadas por espaços em branco e uma coluna adicional que contém espaços que você deseja manter.

Exemplo com N = 2:

1.1 1.2 data for row1
  2.1   2.2    data   for    row2
?  ?   data   for   row3
 \ * data for   row4

Eu gostaria de produzir:

data for row1
data   for    row2
data   for   row3
data for   row4

No shell você pode fazer isso facilmente com:

while read -r _ _ data
do
    printf "%s\n" "$data"
done < data.txt

Mas com awkisso é meio difícil. Existe um método awkpara dividir apenas as primeiras N colunas?

bash
  • 3 3 respostas
  • 85 Views

3 respostas

  • Voted
  1. The fourth bird
    2024-05-26T16:20:52+08:002024-05-26T16:20:52+08:00

    Se os dados estiverem separados por 1 ou mais espaços, você poderá remover as primeiras 1 ou 2 colunas com sub, onde a coluna é uma única palavra composta por caracteres que não são espaços em branco.

    Como seu script de shell de exemplo também removerá a palavra se houver apenas uma palavra, você pode usar uma parte opcional para a segunda palavra.

    awk '{
        sub(/^[[:space:]]*[^[:space:]]+([[:space:]]+[^[:space:]]+)?[[:space:]]*/, "");
    }1' file
    

    O padrão corresponde:

    • ^Início da sequência
    • [[:space:]]*[^[:space:]]+Combine espaços opcionais e mais de 1 caractere sem espaço em branco
    • ([[:space:]]+[^[:space:]]+)?Opcionalmente, combine 1+ caracteres sem espaço em branco seguidos por 1+ espaços
    • [[:space:]]*Corresponder espaços finais

    Entrada

    1.1 1.2 data for row1
      2.1   2.2    data   for    row2
    test
    
    ?  ?   data   for   row3
     \ * data for   row4
    

    Saída

    data for row1
    data   for    row2
    
    
    data   for   row3
    data for   row4
    
    • 2
  2. Daweo
    2024-05-26T19:06:55+08:002024-05-26T19:06:55+08:00

    Isenção de responsabilidade : esta solução pressupõe que você esteja usando AWKo entendimento GNU padrão de campos, ou seja, o separador de campo é um ou mais caracteres de espaço em branco; se isso não for válido, ignore esta resposta completamente.

    Existe um método no awk para dividir apenas as primeiras N colunas?

    Se você conhece N a priori, você pode preparar uma expressão regular e usá-la em subString Function , nesse particular, deixe file.txto conteúdo ser

    1.1 1.2 data for row1
      2.1   2.2    data   for    row2
    ?  ?   data   for   row3
     \ * data for   row4
    

    então

    awk '{sub(/[[:space:]]*[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+/,"");print}' file.txt
    

    dá saída

    data for row1
    data   for    row2
    data   for   row3
    data for   row4
    

    Explicação: a expressão regular consiste em caracteres de espaço em branco alternados [[:space:]]e caracteres que não sejam de espaço em branco [^[:space:]], os caracteres de espaço em branco iniciais são opcionais, portanto, há zero ou mais ( *), todos os outros ou 1 ou mais ( +) em número.

    Se você precisar de uma maneira fácil de ajustar N, use foro loop para remover a coluna mais à esquerda, uma por uma, por exemplo, se você desejasse N = 3 e processasse file.txtcomo mostrado acima, você poderia fazer

    awk 'BEGIN{n=3}{for(i=0;i<n;i+=1){sub(/[[:space:]]*[^[:space:]]+[[:space:]]+/,"")};print}' file.txt
    

    que dá saída

    for row1
    for    row2
    for   row3
    for   row4
    

    Explicação: isso remove a coluna mais à esquerda e o separador de campo adjacente em cada volta do forloop.

    (testado em GNU Awk 5.1.0)

    • 2
  3. Best Answer
    Ed Morton
    2024-05-27T01:01:52+08:002024-05-27T01:01:52+08:00

    A premissa da linguagem awk é que deve haver apenas construções para fazer coisas que não são fáceis de fazer com outras construções para manter a linguagem concisa e assim evitar o inchaço da linguagem que algumas outras ferramentas/linguagens sofrem. Esta é apenas uma das muitas coisas que seria bom ter uma função para fazer, mas é tão fácil codificar tudo o que você realmente precisa fazer para pular alguns campos para qualquer entrada específica que seria apenas uma confusão a linguagem se existisse uma função para fazer isso e se tivéssemos uma função para ISTO, existem centenas de outras funções que também deveriam ser criadas para fazer todas as outras coisas, seria bom ter uma função para fazer.

    Usando GNU awk para \s/\Sabreviação

    $ awk 'sub(/^\s*(\S+\s+){2}/,"")' file
    data for row1
    data   for    row2
    data   for   row3
    data for   row4
    

    e o mesmo com qualquer awk POSIX:

    $ awk 'sub(/^[[:space:]]*([^[:space:]]+[[:space:]]+){2}/,"")' file
    data for row1
    data   for    row2
    data   for   row3
    data for   row4
    

    Observe que a saída do awk acima reteria qualquer espaço em branco à direita, ao contrário de um loop de leitura do shell.

    Ambos dependem de FSser o caractere em branco padrão, mas são facilmente modificados para qualquer outro FSque possa ser negado em uma expressão de colchetes (ou classe de caractere oposta).

    Observe que toda a abordagem depende da capacidade de negar a FSexpressão entre colchetes, para que não funcione se houver FSalgum regexp arbitrário ou mesmo uma string com vários caracteres, mas o loop de leitura do shell que você está pedindo para duplicar também não funcionaria. função de.

    Se acontecer de você ter um, FSvocê não pode simplesmente negar uma expressão entre colchetes, por exemplo, se seus campos estiverem separados por 3 dígitos ou 2 caracteres de pontuação, você terá algo como:

    $ echo 'abc345def;%ghi+klm;%nop345qrs' |
        awk -v FS='[[:digit:]]{3}|[[:punct:]]{2}' '{for (i=1; i<=NF; i++) print i, $i}'
    1 abc
    2 def
    3 ghi+klm
    4 nop
    5 qrs
    

    então aqui está uma abordagem mais geral usando GNU awk para o quarto argumento para split():

    $ echo 'abc345def;%ghi+klm;%nop345qrs' |
        awk -v FS='[[:digit:]]{3}|[[:punct:]]{2}' '{
            split($0,f,FS,s)
            print substr( $0, length(s[0] f[1] s[1] f[2] s[2]) + 1 )
        }'
    ghi+klm;%nop345qrs
    
    • 2

relate perguntas

  • (macOS Bash) 2 strings aparentemente idênticas não são iguais, mostrando apenas diferenças com "set -x"

  • Xargs: a substituição do alias falha apesar de expandir o alias

  • Diferença entre $PATH e ${PATH:+:${PATH}} em ambientes Linux

  • awk localize e substitua por regex e variável de ambiente

  • Como preencher nomes de arquivo com zeros de strings alfanuméricas numeradas e delimitadas de comprimento arbitrário no bash?

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