Sloupec bez poslední postavy s awk a printf

0

Otázka

Mám tento skript:

#!/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

Tento skript mi dává takový výsledek:

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

a já jsem hledat, jak odstranit ".služby" z 3d sloupce.

Snažil jsem se s substr($i, 0, -8) a ${1:-8}

Má někdo nějaký nápad, jak se zbavit 8 znaků od konce aby to vypadalo takhle:

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

Nejlepší odpověď

0

Nikdy jste třeba grep, když jste pomocí awk od grep 'foo' file | awk '{print 7}' může být napsán jen jako awk '/foo/{print 7}' file.

Spíše než počítání znaků, stačí odstranit vše, co od posledního .:

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

Jsem také zpřísnit vaše srovnání, aby se zabránilo falešných shod, když volal s názvem služby, která je podmnožinou nějaké další název služby nebo obsahuje regexp metachars jako ..

2021-11-23 12:10:21

Děkuji za mega rychlou odpověď. Děkuji také za radu, "grep" a "awk" - budu to mít na paměti. Strávil jsem 4 hodiny na tento úkol a neměl jsem tušení, jak to vyřešit.
gacek

Vybral jsem si Vaše řešení a následoval své doporučení pro post-chování odezvy. Ještě jednou děkuji a s pozdravem!
gacek
0

Potřebujete vypočítat koncové polohy založené na délce řetězce, zvažte následující jednoduchý příklad, ať file.txt obsah

cron.service
ssh.service

pak

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

výstup

cron
ssh

Vysvětlení: argumenty pro substr jsou string, počáteční pozice, koncová poloha, length vrátí počet znaků v řetězci.

(testováno v čumět 4.2.1)

2021-11-23 12:04:06

Děkuji Vám za vysvětlení. Zkoušel jsem tímto způsobem předtím: substr($1, délka, -8), ale nemyslel jsem si, že bych měl specifikovat proměnné, které by měl spočítat počet znaků.
gacek

@gacekové length při použití bez () je jen proměnná drží počet znaků v celém řádku ($0), spíše než konkrétní oblasti, například pokud by jste soubor s jednotlivými řádky: 123 456 pak {print length} dává 7,, jak to má 6 číslic a prostoru.
Daweo

pokud jde length when used without () is just variable - ne, pořád je to volání funkce, je to jen zkratka pro length($0). Kdyby to byla proměnná pak, mimo jiné, můžete přiřadit hodnotu na to ale nemůžete.
Ed Morton
0

můžete použít gsub funkce v awk,jako následující:

 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() je pro to, aby více substituce, zatímco vy jen chcete udělat 1, takže byste měli být pomocí sub() místo toho, 2) první argument pro některý z *sub() funkce je regulární výraz, řetězec, takže byste měli používat regexp /.../ne řetězec "...", oddělovače, 3), měli byste ukotvení regexp se zakončovacím $ takže jste odstranit poslední výskyt na lince, není první, 4), musíte uniknout . v regexp nebo to bude odpovídat libovolný znak, ne jen . budete chtít, aby odpovídaly, 5), že jste dont potřebovat grep a když youre pomocí awk od grep 'cron' | awk '{foo}' = awk '/cron/{foo}'.
Ed Morton

V jiných jazycích

Tato stránka je v jiných jazycích

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