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 / 79426134
Accepted
Rasec Malkic
Rasec Malkic
Asked: 2025-02-10 13:25:30 +0800 CST2025-02-10 13:25:30 +0800 CST 2025-02-10 13:25:30 +0800 CST

Extrair linhas após a string e imprimir vários valores em uma única linha

  • 772

Tenho vários arquivos com um formato como este

some text
some text
This section is for WXYZ
some text
some text
some text
some text
some text
some text (ABC) some text (CDF)
901 98
some text FFG
some text (FFG)
1 99
some text
some text

Estou tentando imprimir para cada arquivo

  1. o nome do arquivo
  2. a string após "Esta seção é para" na mesma linha
  3. a linha abaixo da string contendo(ABC)
  4. a linha abaixo da string contendo(FFG)

Este é meu script atual (com base na resposta neste tópico )

awk '/This section is for/{sub(/This section is for /,""); print FILENAME "|" $0}
     a{print;a=0} /\(ABC\)/{a=1}
     b{print;b=0} /\(FFG\)/{b=1}
' "testfile.txt"

Estou obtendo esta saída

testfile.txt|WXYZ
901 98
1 99

E minha saída desejada para cada arquivo seria uma única linha como esta

testfile.txt|WXYZ|901 98|1 99

Como modificar o script para obter meu objetivo? Obrigado

awk
  • 3 3 respostas
  • 41 Views

3 respostas

  • Voted
  1. Best Answer
    Gilles Quénot
    2025-02-10T13:32:57+08:002025-02-10T13:32:57+08:00

    Assim, usando printf "%s"para evitar quebras de linha:

    $ awk '/This section is for/{sub(/This section is for /,""); printf "%s", FILENAME "|" $0}
         a{printf "|%s", $0;a=0} /\(ABC\)/{a=1}
         b{printf "|%s\n", $0;b=0} /\(FFG\)/{b=1}
    ' testfile.txt
    testfile.txt|WXYZ|901 98|1 99
    
    • 1
  2. Ed Morton
    2025-02-10T20:38:16+08:002025-02-10T20:38:16+08:00

    Sempre que tenho uma entrada que contém pares de tag-valor, acho útil primeiro construir uma matriz desses mapeamentos ( f[]abaixo) para separar a detecção do valor do uso do valor e, então, posso imprimir, comparar e modificar em qualquer ordem e combinação que eu quiser, apenas indexando a matriz com sua tag (nome).

    Por exemplo, usando qualquer awk:

    awk -v OFS='|' '
        /^This section is for/ { f["sect"] = $NF }
        tag != "" { f[tag] = $0; tag = "" }
        match($0, /\([^()]+)/) { tag = substr($0,RSTART+1,RLENGTH-2) }
        END { print FILENAME, f["sect"], f["ABC"], f["FFG"] }
    ' "testfile.txt"
    testfile.txt|WXYZ|901 98|1 99
    

    Observe que isso forneceria consistentemente 4 |campos de saída separados, mesmo se alguma das tags estivesse faltando em um arquivo de entrada.

    Já que você disse:

    Tenho vários arquivos...

    se você quisesse processar todos os arquivos de entrada de uma vez, você poderia fazer isso com o GNU awk:

    awk -v OFS='|' '
        /^This section is for/ { f["sect"] = $NF }
        tag != "" { f[tag] = $0; tag = "" }
        match($0, /\(([^()]+))/, a) { tag = a[1] }
        ENDFILE {
            print FILENAME, f["sect"], f["ABC"], f["FFG"]
            delete f
        }
    ' *.txt
    

    ou isso com qualquer awk:

    awk -v OFS='|' '
        FNR == 1 { prt() }
        /^This section is for/ { f["sect"] = $NF }
        tag != "" { f[tag] = $0; tag = "" }
        match($0, /\([^()]+)/) { tag = substr($0,RSTART+1,RLENGTH-2) }
        END { prt() }
    
        function prt() {
            if ( prevFname != "" ) {
                print prevFname, f["sect"], f["ABC"], f["FFG"]
                delete f
            }
            prevFname = FILENAME
        }
    ' *.txt
    
    • 0
  3. Daweo
    2025-02-10T20:53:01+08:002025-02-10T20:53:01+08:00

    O GNU AWKadiciona um separador de linha de saída ao conteúdo de print, que por padrão é uma nova linha ( \n), você pode alterá-lo definindo outro ORSvalor, neste caso específico, deixe testfile.txto conteúdo ser

    some text
    some text
    This section is for WXYZ
    some text
    some text
    some text
    some text
    some text
    some text (ABC) some text (CDF)
    901 98
    some text FFG
    some text (FFG)
    1 99
    some text
    some text
    

    então

    awk 'BEGIN{ORS="|"}/This section is for/{sub(/This section is for /,""); print FILENAME "|" $0}
         a{print;a=0} /\(ABC\)/{a=1}
         b{print;b=0} /\(FFG\)/{b=1}
    ' "testfile.txt"
    

    vai dar

    testfile.txt|WXYZ|901 98|1 99|
    

    Observe que há uma quebra |de linha no final, isso pode ser corrigido da seguinte maneira

    awk 'BEGIN{ORS="|"}/This section is for/{sub(/This section is for /,""); print FILENAME "|" $0}
         a{print;a=0;ORS="\n"} /\(ABC\)/{a=1}
         b{print;b=0;ORS="\n"} /\(FFG\)/{b=1}
    ' "testfile.txt"
    

    que dá saída

    testfile.txt|WXYZ|901 98|1 99
    

    Explicação: Eu mudo ORSpara nova linha após printing a primeira de duas linhas, independentemente de quais linhas ( aou b) vêm primeiro. Se você quiser saber mais sobre ORS, leia 8 Variáveis ​​Internas Poderosas do Awk – FS, OFS, RS, ORS, NR, NF, FILENAME, FNR

    (testado no GNU Awk 5.3.1)

    • 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

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

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

    • 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

    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
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +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

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