Coloana fără ultimele caractere cu awk și printf

0

Problema

Am acest 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

Acest script dă-mi un astfel de rezultat:

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

și am de căutare cum de a elimina ".serviciul" de la 3d coloana.

Am incercat cu substr($i, 0, -8) și ${1:-8}

Are cineva vreo idee cum sa scap de 8 caractere de la sfârșitul pentru a face să arate astfel:

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

Cel mai bun răspuns

0

N-ai nevoie de grep când ești folosind awk din grep 'foo' file | awk '{print 7}' poate fi scris ca doar awk '/foo/{print 7}' file.

Mai degrabă decât de numărare de caractere, doar elimina tot incepand de la ultima .:

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

Am înăsprit, de asemenea, dumneavoastră comparație pentru a evita false meciuri daca numit cu un nume de serviciu care este un subset al unor alte nume de serviciu sau conține regexp metachars ca ..

2021-11-23 12:10:21

Vă mulțumesc pentru mega răspuns rapid. Mulțumesc, de asemenea, pentru sfaturi cu privire la "grep" și "awk" - am să țin minte asta. Mi-am petrecut 4 ore pe sarcina si nu am avut nici o idee cum să-l rezolve.
gacek

Am ales solutia Ta și a urmat recomandările dumneavoastră pentru post-răspuns comportament. Multumesc din nou si toate cele bune!
gacek
0

Aveți nevoie pentru a calcula poziția finală pe baza string lungime, luați în considerare următorul exemplu simplu, să file.txt conținutul fi

cron.service
ssh.service

apoi

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

ieșire

cron
ssh

Explicație: argumente pentru substr sunt de coarde, poziția de start, end poziție, length întoarce numărul de caractere din șir.

(testat în bălălău 4.2.1)

2021-11-23 12:04:06

Mulțumesc pentru explicație. Am încercat în acest fel înainte: substr($1, lungime, -8), dar eu nu cred că ar trebui să specificați o variabilă care ar trebui să conta numărul de caractere.
gacek

@gacek length atunci când este utilizat fără () este doar o variabilă care deține numărul de caractere din întreaga linie ($0) mai degrabă decât anumit domeniu, de exemplu daca ai fi fișierul cu linii simple: 123 456 apoi {print length}7, ca are 6 cifre și spațiu.
Daweo

cu privire la length when used without () is just variable - nu, e încă un apel de funcție, e doar o prescurtare pentru length($0). Dacă a fost o variabilă, atunci, printre alte lucruri, veți putea atribui o valoare, dar nu se poate.
Ed Morton
0

puteți utiliza gsub funtion în awk,cum ar fi următoarele:

 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() este pentru a face substituții multiple în timp ce tu vrei să faci doar 1 deci ar trebui să fie folosind sub() în schimb, 2) primul argument pentru oricare dintre *sub() funcții este un regexp, nu un șir de caractere, deci ar trebui să fie folosind regexp /.../nu string "...", delimitatori, 3) ar trebui să se ancoreze regexp cu o rezistență $ deci elimina ultima apariție pe linie, nu prima, 4) ai nevoie pentru a scăpa de . într-un regexp sau se va potrivi orice caracter, nu doar . doriți să se potrivească, 5) nu ai nevoie de grep când ești folosind awk deoarece grep 'cron' | awk '{foo}' = awk '/cron/{foo}'.
Ed Morton

În alte limbi

Această pagină este în alte limbi

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