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 / 790219
Accepted
vrms
vrms
Asked: 2025-01-27 20:18:20 +0800 CST2025-01-27 20:18:20 +0800 CST 2025-01-27 20:18:20 +0800 CST

awk - como imprimir todos os campos depois de $5?

  • 772

Eu tenho uma saída semelhante a

  975  Jan/21 - 19:59:36 ### sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
  986  Jan/21 - 20:04:21 ### grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"

agora quero reduzir cada linha a tudo depois $5, para obter o comando completo real?

Acho que poderia fazer | awk {'print $6, $7, $8, $9, $10, $11'}... etc. Mas isso parece muito anticientífico, pouco flexível e feio.

Alguém pode me aconselhar como fazer isso ou estou no caminho errado awkpara começar?

awk
  • 10 10 respostas
  • 1512 Views

10 respostas

  • Voted
  1. icarus
    2025-01-27T21:40:16+08:002025-01-27T21:40:16+08:00

    Os dados de exemplo parecem ser de um histórico de comando, provavelmente um número de comando, uma data, uma hora, a sequência ### e então o comando. Nos dados de exemplo, tudo parece se alinhar bem, então o problema se torna "Como me livro dos primeiros 29 caracteres?". Awk não deve ser sua primeira escolha, pois você provavelmente quer preservar lugares onde há mais de um espaço, e isso significa que awk dividir as coisas em campos não é útil para você.

    cut -c 30-
    

    é uma maneira de fazer isso. Uma segunda maneira é observar que há uma string fixa ### , e que não há #caracteres antes disso. Então você pode usar uma expressão regular para corresponder ao início da linha, zero ou mais caracteres que não são #, e então a string fixa e removê-los. A vantagem dessa abordagem é que se os dados mudarem, por exemplo, se o número do comando ficar tão grande que uma coluna extra seja necessária para armazenar o valor, nenhuma mudança será necessária neste programa.

    sed 's/^[^#]*### //'
    

    Você pode usar gsubo awk para fazer o mesmo, se realmente quiser usar o awk.

    • 8
  2. Best Answer
    Fravadona
    2025-01-28T03:23:34+08:002025-01-28T03:23:34+08:00

    Aqui está uma maneira de cortar tudo antes do primeiro  ###  com POSIX awk:

    awk 'match($0, / ### /) {print substr($0, RSTART+RLENGTH)}'
    

    nota: também descarta as linhas que não contêm ### 

    • 8
  3. Chris Davies
    2025-01-27T20:44:57+08:002025-01-27T20:44:57+08:00

    Você pode usar sed, supondo que ###não apareça várias vezes em uma linha:

    sed 's/^.* ### //'
    

    Saída

    sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    
    • 6
  4. Gilles Quénot
    2025-01-27T20:45:47+08:002025-01-27T20:45:47+08:00

    Com uma Perllinha para imprimir tudo depois da coluna 5:

    perl -lane 'print join " ", @F[4..$#F]' file
    

    usando uma fatia de matriz .

    Ao usar -aswitch, Perlcomporte-se como awke divida em espaços por padrão em @Farray. Você pode usar também -Fpara definir o separador de campo (pode ser um regex).

    • 5
  5. Stéphane Chazelas
    2025-01-28T16:58:35+08:002025-01-28T16:58:35+08:00

    Com grepimplementações que suportam -o(para emitir a parte correspondente) e -P(para expressões regulares do tipo Perl):

    grep -Po '\s+###\s+\K.*'
    

    Imprimiria o que viesse depois da primeira ocorrência de <whitespace>###<whitespace>em cada linha.

    grep -Po '^\s*(\S+\s+){5}\K.*'
    

    Para imprimir o que vem depois dos primeiros 5 campos delimitados por espaços em branco.

    • 3
  6. Scottie H
    2025-01-29T04:03:30+08:002025-01-29T04:03:30+08:00

    Uma resposta mais genérica, caso alguém tenha uma pergunta semelhante com um conjunto de dados diferente:

    awk '{$1=$2=$3=$4=$5="";$0=$0;print}' [path/to/data_file]
    

    A primeira parte $1=$2=$3=$4=$5=""define os primeiros 5 campos para o caractere vazio. A desvantagem disso é que o awk ainda lembra que id tinha esses campos, então print $0deixará um espaço vazio na frente da linha de saída.

    Assim, a segunda parte $0=$0remove os espaços em branco iniciais e finais.

    A terceira parte print $0então imprime a nova linha encurtada.

    • 3
  7. terdon
    2025-01-27T20:30:29+08:002025-01-27T20:30:29+08:00

    Sim, você está no caminho errado com awk. Quer dizer, você pode fazer isso no awk, e eu vou te mostrar como em um momento, mas há outra ferramenta, cutque é projetada precisamente para isso. Se você quiser imprimir todos os campos do 5º até o último, você pode simplesmente fazer:

    cut -d ' ' -f 5-
    

    O -d ' ' diz cutpara usar um espaço como delimitador porque uto padrão é usar TAB. Então, o -fé usado para dizer quais campos imprimir e aqui estamos dizendo para imprimir do 5º até o final ( 5-).

    Agora, se seu arquivo não estiver bem estruturado, se você puder ter, digamos, um ou mais espaços como delimitador, awk seria a melhor escolha, mas é mais complexo. Você poderia fazer algo assim, por exemplo:

    awk '{ line=$5; for(i=6;i<=NF;i++){ line=line OFS $(i)} print line}'
    

    Mas isso ainda alteraria o número de espaços em algo como:

    $ echo "a b c d e           f   g" | awk '{ line=$5; for(i=6;i<=NF;i++){ line=line OFS $(i)} print line}'
    e f g
    

    Onde cutnão iria:

    $ echo "a b c d e           f   g" | cut -d ' ' -f 5-
    e           f   g
    

    Tenho certeza de que você pode obter uma solução awk mais elegante, mas, na verdade, cutesta é a ferramenta certa aqui.

    • 2
  8. Ed Morton
    2025-01-28T05:18:24+08:002025-01-28T05:18:24+08:00

    Usando qualquer awk POSIX:

    $ awk '{sub(/^[[:space:]]*([^[:space:]]+[[:space:]]+){5}/,"")} 1' file
    sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    

    ou GNU awk para \s/ \S:

    $ awk '{sub(/^\s*(\S+\s+){5}/,"")} 1' file
    sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    

    ou POSIX sed:

    $ sed 's/^[[:space:]]*\([^[:space:]]\{1,\}[[:space:]]\{1,\}\)\{5\}//' file
    sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    

    ou sed que tenha uma -Eopção para suportar EREs (por exemplo, seds GNU e BSD):

    $ sed -E 's/^[[:space:]]*([^[:space:]]+[[:space:]]+){5}//' file
    sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    

    ou GNU sed para -Ee \s/ \S:

    $ sed -E 's/^\s*(\S+\s+){5}//' file
    sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    
    • 2
  9. jmf7
    2025-01-31T08:35:17+08:002025-01-31T08:35:17+08:00

    awk '{para (i=6;i<=NF;i++) printf("%s%s",(i==6)? "":" ",$i); printf("\n"); } ' arquivo.txt

    • 0
  10. jubilatious1
    2025-02-01T14:32:50+08:002025-02-01T14:32:50+08:00

    Usando Raku (anteriormente conhecido como Perl_6)

    ~$ raku -ne 'put .words[5..*];'  file
    
    #OR:
    
    ~$ raku -ne 'put .comb(/ \S+ /)[5..*];'  file
    

    As respostas do Raku acima foram escritas para complementar a excelente resposta do Perl postada por @GillesQuénot. Para one-liners, o Raku simplifica o número de flags de linha de comando enquanto adiciona mais algumas rotinas para compensar.

    • Os -nesinalizadores de linha de comando instruem o Raku a executar o código linha a linha sem impressão automática ( awkcomportamento semelhante ao ).
    • Na primeira resposta, a .wordsrotina é uma abreviação que $_.wordssignifica interromper a entrada de texto em espaços em branco.
    • Na segunda resposta, a .combrotina é usada para selecionar globalmente / \S+ /um ou mais caracteres que não sejam espaços em branco.
    • Indexar os elementos resultantes com .[5..*]e então usá-los putpara gerar a saída resultará na fatia desejada de colunas/elementos impressa, com um (único) caractere de espaço em branco como separador.
    • O uso putadicionará automaticamente o caractere de nova linha EOL.

    Exemplo de entrada:

    975  Jan/21 - 19:59:36 ### sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    986  Jan/21 - 20:04:21 ### grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    

    Exemplo de saída:

    sed "/^#include_dir/a include_dir = 'conf.d'" /opt/db/data/efa_bauen_ni_14/postgresql.conf
    grep -l "^port = '5" /opt/db/data/postgres/efa_bauen_ni/conf.d/*.conf | xargs sed -i "s/port = '5/port = '6/"
    

    https://docs.raku.org
    https://raku.org

    • 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