Awk ve printf ile son karakter içermeyen sütun

0

Soru

Bu senaryo bende:

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

Bu senaryo bana böyle bir sonuç veriyor:

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

ve nasıl kaldırılacağını araştırıyorum".3d sütundan" servis".

Substr($i, 0, -8) ve ${1:-8}ile denedim

Böyle görünmesi için 8 karakterden nasıl kurtulacağına dair bir fikri olan var mı:

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

En iyi cevabı

0

O zamandan beri awk kullanırken asla grep'e ihtiyacınız yok grep 'foo' file | awk '{print 7}' sadece olarak yazılabilir awk '/foo/{print 7}' file.

Karakterleri saymak yerine, sondan başlayarak her şeyi kaldırın .:

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

Ayrıca, başka bir hizmet adının bir alt kümesi olan veya aşağıdaki gibi regexp meta karakterleri içeren bir hizmet adıyla çağrılırsa, yanlış eşleşmeleri önlemek için karşılaştırmanızı sıkılaştırdım ..

2021-11-23 12:10:21

Mega hızlı cevap için teşekkür ederiz. "Grep" ve "awk" ile ilgili tavsiyeleriniz için de teşekkürler - bunu aklımda tutacağım. Bu görev için 4 saat harcadım ve nasıl çözüleceği hakkında hiçbir fikrim yoktu.
gacek

Çözümünüzü seçtim ve yanıt sonrası davranış önerilerinizi takip ettim. Tekrar teşekkür ederim ve saygılarımla!
gacek
0

Dize uzunluğuna göre bitiş konumunu hesaplamanız gerekir, aşağıdaki basit örneği göz önünde bulundurun: file.txt içerik olmak

cron.service
ssh.service

sonra

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

çıktı

cron
ssh

Açıklama: argümanlarsubstr dize, başlangıç konumu, bitiş konumu, length dizedeki karakter sayısını döndürür.

(gawk 4.2.1'de test edilmiştir)

2021-11-23 12:04:06

Teşekkür ederim açıklama için. Daha önce bu yolu denedim: substr($1, length, -8), ancak karakter sayısını sayması gereken bir değişken belirtmem gerektiğini düşünmedim.
gacek

@gacek length olmadan kullanıldığında () bütün çizgi karakter sadece değişken holding numarası ($0) belirli bir alan yerine, örneğin tek satırlı dosyanız varsa: 123 456 sonra {print length} verir 7 6 basamak ve boşluğa sahip olduğu için.
Daweo

ilişkin length when used without () is just variable - hayır, hala bir işlev çağrısı, sadece kısaltma length($0). Bir değişken olsaydı, diğer şeylerin yanı sıra, ona bir değer atayabilirdiniz, ancak yapamazsınız.
Ed Morton
0

kullanabilirsiniz gsub awk'deki işlev, aşağıdaki gibi:

 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() bu, yalnızca 1 yapmak istediğiniz sürece birden fazla değişiklik yapmak içindir, bu yüzden kullanmanız gerekir sub() bunun yerine, 2) herhangi biri için ilk argüman *sub() işlevler bir dizge değil, bir regexp'dir, bu nedenle regexp kullanıyor olmalısınız /.../, dize değil "...", sınırlayıcılar, 3) regexp'inizi bir sonlandırma ile sabitlemelisiniz $ böylece, ilk değil, satırdaki son olayı kaldırırsınız, 4) kaçmanız gerekir . bir regexp'de veya herhangi bir karakterle eşleşecek, sadece . eşleştirmek istiyorsun, 5) ihtiyacın yok grep ne zaman kullanıyorsun awk dan beri grep 'cron' | awk '{foo}' = awk '/cron/{foo}'.
Ed Morton

Diğer dillerde

Bu sayfa diğer dillerde

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