Columna sin pasado caracteres con awk y printf

0

Pregunta

Tengo 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 da un resultado:

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

y yo buscar cómo quitar ".servicio" de la columna 3d.

He probado con substr($i, 0, -8) y ${1:-8}

¿Alguien tiene alguna idea de cómo deshacerse de 8 caracteres desde el final para que se vea así:

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

Mejor respuesta

0

Usted nunca necesita grep cuando usted está usando awk desde grep 'foo' file | awk '{print 7}' puede ser escrito como sólo awk '/foo/{print 7}' file.

En vez de contar los caracteres, acaba de quitar todo a partir de la última .:

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
    }
'

Yo también reforzó su comparación, para evitar falsos partidos si se llama con un nombre de servicio que es un subconjunto de algún otro servicio o nombre contiene regexp metachars como ..

2021-11-23 12:10:21

Gracias por mega rápida respuesta. Gracias también por los consejos sobre "grep" y "awk" - lo tendré en mente. Me pasé 4 horas en esta tarea y no tenía ni idea de cómo resolverlo.
gacek

Elegí Tu solución y seguido sus recomendaciones para después de la respuesta de comportamiento. Gracias de nuevo y saludos!
gacek
0

Usted necesita para calcular la posición final que se basa en la longitud de la cadena, considere el siguiente ejemplo sencillo, vamos a file.txt del contenido de la

cron.service
ssh.service

entonces

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

salida

cron
ssh

Explicación: argumentos para substr son de cadena, de posición inicial, la posición final, length devolver el número de caracteres en la cadena.

(probado en gawk 4.2.1)

2021-11-23 12:04:06

Gracias por la explicación. He intentado de esta manera antes: substr($1, longitud, -8), pero no creo que me debe especificar una variable que debe contar el número de caracteres.
gacek

@gacek length cuando se utiliza sin () es sólo la variable que contiene el número de caracteres en toda la línea ($0) en lugar de campo en particular, por ejemplo si queremos tener un archivo con líneas simples: 123 456 entonces {print length} da 7, como consta de 6 dígitos y el espacio.
Daweo

con respecto a length when used without () is just variable - no, es todavía una llamada a una función, es sólo una abreviatura para el length($0). Si fuera una variable y luego, entre otras cosas, se podría asignar un valor a la misma pero no se puede.
Ed Morton
0

puede utilizar gsub funtion en awk,como los siguientes:

 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() es para hacer múltiples sustituciones, mientras que sólo desea hacer 1 por lo que debe ser el uso de sub() en su lugar, 2) el primer argumento para cualquiera de los *sub() funciones es un regexp, no una cadena, por lo que debe ser el uso de regexp /.../, no de cadena "...", delimitadores, 3) se debe anclar su regexp con una terminación de $ lo de quitar la última aparición en la línea, no el primero, 4) usted necesita para escapar de la . en un regexp o que va a hacer coincidir cualquier carácter, no sólo la . desea igualar 5) usted no necesita grep cuando se está utilizando awk desde grep 'cron' | awk '{foo}' = awk '/cron/{foo}'.
Ed Morton

En otros idiomas

Esta página está en otros idiomas

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