Coluna sem caracteres última com awk e printf

0

Pergunta

Eu tenho este script:

#!/bin/bash

f_status () {
        systemctl list-units | grep $1 | awk '{ printf("SERVICE STATUS:  %-25s \t %s \t %s \t %s\n",$1,$2,$3,$4) }'
}

f_line() {
        echo "-------------------------------------------------------------------------------------------"
}

echo ""
f_line
f_status "cron"
f_status "ssh"
f_line

Este script me dá esse resultado:

-------------------------------------------------------------------------------------------
SERVICE STATUS:  cron.service                    loaded          active          running
SERVICE STATUS:  ssh.service                     loaded          active          running
-------------------------------------------------------------------------------------------

e eu de pesquisa como remover ".serviço" a partir do 3d coluna.

Eu tentei com substr($i, 0, -8) e ${1:-8}

Alguém tem alguma idéia de como se livrar de 8 caracteres a partir do fim de torná-lo parecido com este:

-----------------------------------------------------------------------------------
SERVICE STATUS:  cron                    loaded          active          running
SERVICE STATUS:  ssh                     loaded          active          running
-----------------------------------------------------------------------------------
awk bash printf
2021-11-23 11:39:15
3

Melhor resposta

0

Você nunca precisa grep quando você estiver usando awk desde grep 'foo' file | awk '{print 7}' pode ser escrito como apenas awk '/foo/{print 7}' file.

Em vez de contar caracteres, basta remover tudo a partir do último .:

systemctl list-units |
awk -v tgt="$1" '
    {
        svc = $1
        sub(/\.[^.]*$/,"",svc)
    }
    svc == tgt {
        printf "SERVICE STATUS:  %-25s \t %s \t %s \t %s\n",svc,$2,$3,$4
    }
'

Eu também apertados até a sua comparação, para evitar falsas partidas se a chamada com um nome de serviço é um subconjunto de algum outro nome de serviço ou contém regexp metachars como ..

2021-11-23 12:10:21

Obrigado por mega rápida resposta. Obrigado também para o aconselhamento sobre "grep" e "awk" - eu vou manter isso em mente. Eu passei 4 horas nesta tarefa e eu não tinha idéia de como resolvê-lo.
gacek

Eu escolhi a Sua solução e seguido suas recomendações para o pós-resposta do comportamento. Obrigado novamente e os melhores cumprimentos!
gacek
0

Você precisa calcular a posição final com base na seqüência de caracteres de comprimento, considere o seguinte exemplo simples, vamos file.txt conteúdo

cron.service
ssh.service

em seguida,

awk '{print substr($1,1,length($1)-8)}' file.txt

saída

cron
ssh

Explicação: argumentos para substr são de cadeia, de posição inicial, posição final, length retornar o número de caracteres na seqüência de caracteres.

(testado em basbaque 4.2.1)

2021-11-23 12:04:06

Obrigado pela explicação. Eu tentei dessa forma antes: substr($1, comprimento, -8), mas eu não acho que eu deveria especificar uma variável que deve contar o número de caracteres.
gacek

@gacek length quando usado sem () é apenas a variável com o número de caracteres em toda a linha ($0) em vez de determinado campo, por exemplo, se você teria arquivo com linhas simples: 123 456 em seguida, {print length}7, como ele tem 6 dígitos e no espaço.
Daweo

sobre length when used without () is just variable - não, é ainda uma chamada de função, é apenas um atalho para length($0). Se fosse uma variável, então, entre outras coisas, você pode atribuir um valor a ela, mas você não pode.
Ed Morton
0

você pode usar gsub cortaram o funtion em awk,como o seguinte:

 systemctl list-units | grep 'cron' | awk '{gsub(".service","",$1); printf("SERVICE STATUS:  %-25s \t %s \t %s \t %s\n",$1, $2 ,$3,$4) }'
SERVICE STATUS:  crond                       loaded      active      running
2021-11-23 12:04:26

1) gsub() é para fazer várias substituições, enquanto você só quer fazer 1 portanto, você deve estar usando sub() em vez disso, 2) o primeiro argumento para qualquer um dos *sub() funções é uma regexp, não uma seqüência de caracteres, então você deve estar usando regexp /.../, não de cadeia "...", delimitadores, 3) você deve ancorar seu regexp com uma terminação $ então você remover a última ocorrência na linha, não o primeiro, 4) você precisa escapar da . em uma regexp ou ele vai corresponder a qualquer carácter, não apenas o . você deseja corresponder, 5) você não precisa grep quando você estiver usando awk desde grep 'cron' | awk '{foo}' = awk '/cron/{foo}'.
Ed Morton

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................