Colonna senza gli ultimi caratteri con awk e printf

0

Domanda

Ho questo 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

Questo script mi dà questo risultato:

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

e mi cerca come rimuovere ".servizio" dal 3d di colonna.

Ho provato con la funzione substr($i, 0, -8) e ${1:-8}

Qualcuno ha qualche idea di come sbarazzarsi di 8 caratteri dalla fine di renderlo simile a questa:

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

Migliore risposta

0

Non hai mai bisogno di grep quando si utilizza awk dal grep 'foo' file | awk '{print 7}' può essere scritto come solo awk '/foo/{print 7}' file.

Piuttosto che contare i caratteri, basta rimuovere il tutto a partire dall'ultimo .:

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

Ho anche rafforzato il confronto per evitare false partite se chiamato con il nome di un servizio che è un sottoinsieme di qualche altro nome del servizio o contiene regexp metachars come ..

2021-11-23 12:10:21

Grazie per il mega veloce risposta. Grazie anche per i consigli sul "grep" e "awk" - terrò a mente. Ho passato 4 ore a svolgere questo compito e non avevo idea di come risolverlo.
gacek

Ho scelto la Tua soluzione e seguito le tue raccomandazioni per la post-comportamento di risposta. Grazie ancora e cordiali saluti!
gacek
0

Devi calcolare la posizione finale basato sulla lunghezza della stringa, considerare il seguente semplice esempio, si file.txt il contenuto di

cron.service
ssh.service

quindi

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

uscita

cron
ssh

Spiegazione: argomenti per substr sono stringa, posizione iniziale posizione finale, length restituisce il numero di caratteri nella stringa.

(testato in gawk 4.2.1)

2021-11-23 12:04:06

Grazie per la spiegazione. Ho provato in questo modo prima: substr($1, lunghezza, -8), ma non pensavo che avrei dovuto specificare una variabile che conta il numero di caratteri.
gacek

@gacek length quando utilizzato senza () è appena variabile di partecipazione numero di caratteri in tutta la linea ($0), piuttosto che un campo particolare, per esempio se si hanno file con le singole righe: 123 456 quindi {print length}7come ha 6 cifre e spazio.
Daweo

per quanto riguarda length when used without () is just variable - no, è ancora in una chiamata di funzione, è solo una scorciatoia per length($0). Se fosse una variabile e quindi, tra le altre cose, si potrebbe assegnare un valore, ma non è possibile.
Ed Morton
0

è possibile utilizzare gsub funzione in awk,come la seguente:

 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() è per rendere più sostituzioni mentre si vuole solo fare 1 così si dovrebbe essere utilizzando sub() invece, 2) il primo argomento per uno dei *sub() funzioni è una regexp, non una stringa, così si dovrebbe essere usare le regexp /.../non stringa "...", delimitatori, 3) si dovrebbe ancorare la tua regexp con una terminazione $ quindi si rimuove l'ultima occorrenza sulla linea, non il primo, 4) è necessario sfuggire alla . in una regexp o ti corrisponde a qualsiasi carattere, non solo il . si desidera abbinare, 5) non è necessario grep quando youre utilizzando awk dal grep 'cron' | awk '{foo}' = awk '/cron/{foo}'.
Ed Morton

In altre lingue

Questa pagina è in altre lingue

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