Takže vytažení otevřeného souboru pomocí cat
a poté pomocí grep
pro získání odpovídajících řádků mě dostane tak daleko, až pracuji s konkrétní sadou protokolů, se kterou se zabývám. Potřebuje způsob, jak spojit čáry se vzorkem, ale pouze vrátit část čáry po zápase. Část před a po zápase se bude neustále měnit. Hrál jsem s použitím sed
nebo awk
, ale nebyl jsem schopen přijít na to, jak filtrovat řádek, aby buď část smazal před zápasem, nebo jen část vrátil po zápase, buď bude fungovat. Toto je příklad řádku, který musím filtrovat:
2011-11-07T05:37:43-08:00 <0.4> isi-udb5-ash4-1(id1) /boot/kernel.AMD64/kernel: [gmp_info.c:1758](pid 40370="kt: gmp-drive-updat")(tid=100872) new group: <15,1773>: { 1:0-25,27-34,37-38, 2:0-33,35-36, 3:0-35, 4:0-9,11-14,16-32,34-38, 5:0-35, 6:0-15,17-36, 7:0-16,18-36, 8:0-14,16-32,34-36, 9:0-10,12-36, 10-11:0-35, 12:0-5,7-30,32-35, 13-19:0-35, 20:0,2-35, down: 8:15, soft_failed: 1:27, 8:15, stalled: 12:6,31, 20:1 }
Část, kterou potřebuji, je všechno po „zastavení“.
Pozadím je, že mohu zjistit, jak často něco stojí:
cat messages | grep stalled | wc -l
Co musím udělat, je zjistit, kolikrát se určitý uzel zastavil (označeno částí před každým tlustým střevem po „zastavení“. Pokud za to jen grepím (tj. 20 :), může vrátit řádky, které mají měkké selhání, ale Žádná stání, což mi nepomůže. Potřebuji filtrovat pouze zablokovanou část, abych mohl potom tápat po konkrétním uzlu z těch, které se zastavily.
Pro všechny záměry a účely je to freebsd systém se standardními GNU jádro utils), ale nemohu nainstalovat nic navíc, abych pomohl.
Kanonickým nástrojem by to bylo sed
.
sed -n -e 's/^.*stalled: //p'
Podrobné vysvětlení:
-n
Znamená, že ve výchozím nastavení nic netisknout.-e
Je následován příkazem sed.s
je příkaz nahrazení vzoru.^.*stalled:
Odpovídá vzoru, který hledáte, plus jakýkoli předchozí text (.*
, Což znamená jakýkoli text, s počátečním ^
, Který říká, že zápas začíná na začátek řádku). Pokud se na řádku objeví několikrát stalled:
, Bude to odpovídat poslednímu výskytu.stalled:
, Je nahrazeno prázdným řetězcem (tj. Odstraněno).p
znamená vytisknout transformovanou čáru.Pokud si chcete zachovat odpovídající část, použijte zpětný odkaz: \1
V náhradním dílu označuje, co je uvnitř skupiny \(…\)
ve vzoru. Zde můžete do náhradní části napsat stalled:
; tato funkce je užitečná, když hledaný vzor je obecnější než jednoduchý řetězec.
sed -n -e 's/^.*\(stalled: \)/\1/p'
Někdy budete chtít část zápasu po zápase odstranit. Můžete jej zahrnout do zápasu zahrnutím .*$
Na konec vzoru (jakýkoli text .*
Následovaný koncem řádku $
). Pokud část nezadáte do skupiny, na kterou odkazujete v náhradním textu, nebude konec řádku na výstupu.
Jako další ilustrace skupin a zpětných odkazů tento příkaz zaměňuje část před zápasem a část za zápasem.
sed -n -e 's/^\(.*\)\(stalled: \)\(.*\)$/\3\2\1/p'
Další kanonický nástroj, který již používáte: grep
:
Například:
grep -o 'stalled.*'
Má stejný výsledek jako druhá možnost Gilles:
sed -n -e 's/^.*\(stalled: \)/\1/p'
Příznak -o
Vrací část výrazu --only-matching
, Takže ne celý řádek, který se samozřejmě provádí grepem.
Pro odstranění "zablokovaného:" z výstupu můžeme použít třetí kanonický nástroj, cut:
grep -o 'stalled.*' | cut -f2- -d:
Příkaz cut
používá oddělovač :
A tiskne pole 2 až do konce. Je to samozřejmě otázka preference, ale syntaxi cut
se mi velmi snadno zapamatuje.
Použil jsem ifconfig | grep eth0 | cut -f3- -d:
vzít to
[[email protected] ~]# ifconfig
eth0 Link encap:Ethernet HWaddr AC:B4:CA:DD:E6:F8
inet addr:192.168.0.2 Bcast:192.168.0.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:78998810244 errors:1 dropped:0 overruns:0 frame:1
TX packets:20113430261 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:110947036025418 (100.9 TiB) TX bytes:15010653222322 (13.6 TiB)
a aby to vypadalo takto
[[email protected] ~]# ifconfig | grep eth0 | cut -f3- -d:
C4:7A:4D:F6:B8
Další kanonický nástroj, o kterém jste uvažovali awk
, by mohl být použit s následujícím řádkem:
awk -F"stalled" '/stalled/{print $2}' messages
Podrobné vysvětlení:
-F
definuje oddělovač pro řádek, tj. „zastavený“. Všechno před oddělovačem je adresováno pomocí $1
a všechno poté s $2
./reg-ex/
Vyhledá odpovídající regulární výraz, v tomto případě „zastavený“.{print $<n>}
- tiskne n sloupec. Vzhledem k tomu, že váš oddělovač je definován jako zastavený, považuje se vše po zastavení za druhý sloupec.zdá se, že je to jednodušší. prostě udělej:
sed "s/installed.*//g"
který odebere všechna slova po "nainstalován".
for i in *
do
se=$(echo $i|sed "s/---.*//g")
echo $se
mv "$i" $se
done