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 / 788167
Accepted
Christopher Karsten
Christopher Karsten
Asked: 2024-12-15 23:39:08 +0800 CST2024-12-15 23:39:08 +0800 CST 2024-12-15 23:39:08 +0800 CST

imprima texto entre caracteres especiais na mesma linha e remova os espaços em branco iniciais e finais

  • 772

Estou tentando obter texto entre caracteres especiais. Você pode seguir o abaixo para entender o que estou tentando obter. Tenho os comandos necessários para fazer isso, no entanto, estou procurando uma maneira mais eficiente, caso certas condições possam mudar com base no resultado.

Abaixo tem o texto On-Line (Prim) por exemplo. Quero extrair qualquer texto entre "--" 1ª e 2ª ocorrência.

Então eu tenho o texto abaixo na variável "VAL1"

IBM Informix Dynamic Server Version 14.10.FC10XA -- On-Line (Prim) -- Up 77 days 23:08:31 -- 130337920 Kbytes

Então atualmente estou usando o seguinte:

echo "$VAL1" | awk -F'--' '$1 ~ /Version/ {print $2}'

O acima fornece a saída abaixo:

 On-Line (Prim)

No entanto, você não consegue ver que há necessariamente um espaço em branco no final da linha, mas o início é bem perceptível. Quero garantir que eu imprima apenas as palavras entre "--" que excluam quaisquer espaços em branco antes e depois da frase dentro de "--".

Então tentei usar o seguinte, que para mim parece estar bom:

echo "$VAL1" | awk -F'--' '$1 ~ /Version/ {print $2}' | sed 's/^ //g' | sed 's/ *$//'

Saída:

On-Line (Prim)

Gostaria de saber se existe uma maneira melhor e mais fácil de fazer isso que seja mais suficiente?

awk
  • 4 4 respostas
  • 279 Views

4 respostas

  • Voted
  1. Best Answer
    tink
    2024-12-15T23:51:35+08:002024-12-15T23:51:35+08:00

    Basta estender seu separador de campo de --para  --  ...

    echo 'IBM Informix Dynamic Server Version 14.10.FC10XA -- On-Line (Prim) -- Up 77 days 23:08:31 -- 130337920 Kbytes' |
       awk -F' -- ' '{print $2}'
    On-Line (Prim)
    

    Ou para imprimi-lo somente se houver pelo menos 2 ocorrências de  -- na linha:

    echo 'IBM Informix Dynamic Server Version 14.10.FC10XA -- On-Line (Prim) -- Up 77 days 23:08:31 -- 130337920 Kbytes' |
       awk -F' -- ' 'NF > 2 {print $2}'
    On-Line (Prim)
    

    Ou outra alternativa - usando awk's gsub:

    echo 'IBM Informix Dynamic Server Version 14.10.FC10XA -- On-Line (Prim) -- Up 77 days 23:08:31 -- 130337920 Kbytes' | awk -F'--' '{gsub(/^ +| +$/,"",$2);print $2}'
    On-Line (Prim)
    
    • 4
  2. Stéphane Chazelas
    2024-12-16T15:16:23+08:002024-12-16T15:16:23+08:00

    Como você está no AIX, você deve ter acesso ao shell ksh93 que suporta (uma forma limitada de) expressões regulares perl onde você pode fazer:

    if [[ $VAL1 = ~(P)^(.*?)--\s*(.*?)\s*-- ]]; then
      service=${.sh.match[1]} status=${.sh.match[2]}
      if [[ $service = *Version* ]]; then
        print -r -- "$status"
      fi
    fi
    

    Ou o mesmo com zsh (onde expressões regulares perl são suportadas pela biblioteca PCRE, portanto com suporte mais completo do que no ksh93):

    set -o rematchpcre
    if [[ $VAL1 =~ '^(.*?)--\s*(.*?)\s*--' ]]; then
      Service=$match[1] Status=$match[2]
      if [[ $Service = *Version* ]]; then
        print -r -- $Status
      fi
    fi
    

    (não usar $statusaqui, pois essa é a variável especial que contém o status de saída do último comando, como na maioria dos outros shells (exceto aqueles do tipo Bourne, onde é $?(que o zsh também suporta como um alias)).

    Com awk:

    awk -- '
      BEGIN {
        n = split(ARGV[1], fields, "[[:space:]]*--[[:space:]]*")
        if (n > 2 && field[1] ~ /Version/)
          print field[2]
        else exit !OK
      }' "$VAL1"
    

    Lá, estamos passando o valor de $VAL1 como argumento para, awkem vez de, em seu stdin, o que tem alguns benefícios:

    • é considerado como um todo em vez de cada linha ser processada separadamente. Isso faz diferença se os campos podem conter caracteres de nova linha.
    • echonão pode ser usado para dados arbitrários, pois dependendo da implementação e/ou do ambiente de compilação/execução, ele processa algumas opções e/ou destrói barras invertidas (usar printf '%s\n' "$VAL1"ou print -r -- "$VAL1"em ksh/zsh ou usar um heredoc ou herestring não teria esse problema).
    • menos processos precisam ser gerados e um pipe não precisa ser criado.

    No entanto, observe que como awké um comando externo, isso significa que o valor é visível para qualquer pessoa no sistema (como na saída de psif executado no momento certo) e você pode atingir o execve()limite no tamanho dos argumentos+environ (por padrão, relativamente grande (1 MiB) no AIX 7.{1..3}).

    Passar o valor pelo ambiente evitaria o primeiro problema:

    S=$VAL1 awk '
      BEGIN {
        n = split(ENVIRON["S"], fields, "[[:space:]]*--[[:space:]]*")
        if (n > 2 && field[1] ~ /Version/)
          print field[2]
        else exit !OK
      }'
    

    Assim como FS(conforme definido por -F), o argumento separador de split()é uma expressão regular, então podemos incluir [[:space:]]*(qualquer quantidade de espaço em branco) ao redor --dele.

    • 3
  3. markp-fuso
    2024-12-16T08:48:07+08:002024-12-16T08:48:07+08:00

    Supondo que o OP queira capturar o resultado em outra variável, podemos realizar um par de substituições de parâmetros em vez de invocar alguns subshells para chamar awkou sed, por exemplo:

    $ VAL1='IBM Informix Dynamic Server Version 14.10.FC10XA -- On-Line (Prim) -- Up 77 days 23:08:31 -- 130337920 Kbytes'
    
    $ VAL2="${VAL1#*-- }"         # strip off everything from start of string to first occurrence of "-- "
    $ typeset -p VAL2
    declare -- VAL2="On-Line (Prim) -- Up 77 days 23:08:31 -- 130337920 Kbytes"
    
    $ VAL3="${VAL2%% --*}"        # strip off everything from first occurrence of " --" to the end of the string
    $ typeset -p VAL3
    declare -- VAL3="On-Line (Prim)"
    
    • 1
  4. Dru
    2024-12-17T07:44:49+08:002024-12-17T07:44:49+08:00

    As páginas de informações do GNU awk listam uma biblioteca de funções adicional que pode ter uma função trim...

    Este site tem uma função ok trim que você pode adicionar à 'biblioteca de funções do sistema GAWK' (acho que é um cfg em ~/.gawkrc ou algo assim) --

    https://gist.github.com/andrewrcollins/1592991

    Trim é uma função útil para adicionar à biblioteca. As páginas de informação têm essa 'biblioteca de funções' no diretório inicial, mas não está nas páginas man, etc.

    • 0

relate perguntas

  • remova o número de linhas duplicadas com base na correspondência antes da primeira vírgula

  • anexar linhas após outros arquivos linha por linha

  • Como remover uma única linha entre duas linhas

  • Reorganize as letras e compare duas palavras

  • Embaralhamento de arquivo de várias linhas

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