Toon posts:

awk: aan regel iets vast plakken

Pagina: 1
Acties:
  • 107 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
hoi,
ik wil met awk een regel uit een log html maken, en dus
<br> toevoegen.
Maar in dat log van mij staan regels met allerlei groottes.

Ook wil ik eigenlijk de eerste twee woorden weg hebben. En dan nog sommige dingen rood maken (dus <kleur rood> .. </kleur>) om woorden heen zetten.

Nu kan ik die log lezen met tail -n 500 of zo.
Dan pipen via grep naar awk.

Dan wil ik dus eigenlijk doen:
awk '{print $3 tot $laatste "<br>"}'
maar hoe doe ik dat?

Daarna kan het door sed om wat html toe te voegen.

Wie kan helpen?

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 04-08 07:59

chem

Reist de wereld rond

meer kans in NOS, ipv P&W :)
move...

Klaar voor een nieuwe uitdaging.


Verwijderd

Op woensdag 05 december 2001 20:38 schreef chem het volgende:
meer kans in NOS, ipv P&W :)
move...
Huh? Awk/sed zijn gewoon scripttalen :? Perl move je hier toch ook niet heen of wel dan :?

  • chem
  • Registratie: Oktober 2000
  • Laatst online: 04-08 07:59

chem

Reist de wereld rond

hoeveel programmeurs/webscripters zijn er die awk gebruiken?

ik schat het percentage HEEL laag :)

Ik vermoed dat het aanzienlijk vaker door NOS-bezoekers wordt gebruikt...

Klaar voor een nieuwe uitdaging.


Verwijderd

Ik heb ff zitten te pielen (kan ik mooi m'n kennis van awk opfrissen), en volgens mij is het mogelijk. Eerst even wat algemene dingen vooraf:
Je kunt een logbestand via grep pipen naar awk, maar ook awk kent zoekcriteria. Bijv:
code:
1
/zoekterm/ {print $0}

Dit drukt alleen die regels af die zoekterm bevatten.
In NF zit het totale aantal velden van je regel, in NR het totale aantal regels. Ik kwam dan op het volgende uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
i=3
while ( i <= NF )
    {
    regel=regel$i
        if ( i < NF )
            {
            regel=regel" "
            }
    i=i+1
    }
print regel"<br>"
regel=""
}

Dit stukkie script begint vanaf het derde veld (i=3) opnieuw de variabele regel op te bouwen tot het einde (NF). Zolang i ongelijk is aan NF wordt er nog een spatie achter geplakt, als i gelijk is aan NF gebeurt dant niet. Tenslotte wordt de inhoud van regel afgedrukt naar standaard uitvoer met de string <br> erachteraan.
Als je de uitvoer van dit scriptje in bestandsvorm wil hebben dan kun je de uitvoer op de normale manier omleiden naar een bestand.

Verwijderd

Topicstarter
Op woensdag 05 december 2001 22:27 schreef KrunK het volgende:
Ik heb ff zitten te pielen (kan ik mooi m'n kennis van awk opfrissen), en volgens mij is het mogelijk. Eerst even wat algemene dingen vooraf:
Je kunt een logbestand via grep pipen naar awk, maar ook awk kent zoekcriteria. Bijv:
code:
1
/zoekterm/ {print $0}

damn! Ik ga die howto eens even diep doorspitten. Kan ik dit in een pipe met het onderstaande meenemen?


Dit drukt alleen die regels af die zoekterm bevatten.

In NF zit het totale aantal velden van je regel, in NR het totale aantal regels. Ik kwam dan op het volgende uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
i=3
while ( i <= NF )
    {
    regel=regel$i
        if ( i < NF )
            {
            regel=regel" "
            }
    i=i+1
    }
print regel"<br>"
regel=""
}

moet ik dit script dan als awk script aanroepen in een pipe? Ik ken wel wat awk, maar dit moet ik eens diep laten bezinken.


Dit stukkie script begint vanaf het derde veld (i=3) opnieuw de variabele regel op te bouwen tot het einde (NF).

i is ook een standaart variabele?


Zolang i ongelijk is aan NF wordt er nog een spatie achter geplakt, als i gelijk is aan NF gebeurt dant niet. Tenslotte wordt de inhoud van regel afgedrukt naar standaard uitvoer met de string <br> erachteraan.
Als je de uitvoer van dit scriptje in bestandsvorm wil hebben dan kun je de uitvoer op de normale manier omleiden naar een bestand.
U is geweldig!

Verwijderd

damn! Ik ga die howto eens even diep doorspitten. Kan ik dit in een pipe met het onderstaande meenemen?
...
moet ik dit script dan als awk script aanroepen in een pipe?
De algemene aanroep van awk is als volgt:
code:
1
# awk -f script bestand

waarbij script het awk-script is en bestand het bestand dat je wil parsen. Je kunt het als volgt doen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/zoekterm/ {
i=3
while ( i <= NF )
      {
      regel=regel$i
            if ( i < NF )
                  {
                  regel=regel" "
                  }
      i=i+1
      }
print regel"<br>"
regel=""
}

Stel je noemt bovenstaand script testscript en je te parsen bestand heet firewall.log dan wordt het:
code:
1
# awk -f testscript firewall.log

Wil je dat de output van bovenstaande naar een bestand gaat ipv naar je console doe dan:
code:
1
# awk -f testscript firewall.log > /tmp/output.html

De i is trouwens geen standaard variabele, buiten de gereserveerde variabelen mag je zelf variabelen in het leven roepen.
Oh ja, als je velden niet gescheiden zijn door spaties, kun je dit ook nog instellen. Dit geldt trouwens ook (in mijn script dan) voor de outputfile.
Het is inderdaad aan te raden om eens dieper in awk te duiken, want het is een van de meest krachtige scripttalen van unix.

Verwijderd

Topicstarter
[quote]Op woensdag 05 december 2001 23:01 schreef KrunK het volgende:

Bedanks zeg! Nu heb ik nog 1 vraagje :-)


je wil parsen. Je kunt het als volgt doen:
[code]/zoekterm

als ik niet 1 zoekterm wil , maar juist enkele zoektermen eruit wil filteren. En dan met name een lijstje van drie:-)

Ik weet van "!", maar kun je ook net als met grep een lijstje termen gebruiken? Zoals "authentic" en "alaska"

/ ! "auth" and "alska"/

Verwijderd

Tuurlijk kan dat. Zoals ik al zei, awk roelt onwijs! Je kunt in de zoektermen gebruik maken van reguliere expressies, dus:
code:
1
/blaat/

Zoekt naar regels waarin blaat voorkomt als woord of als onderdeel van een woord.
code:
1
/(blaat) & (blah)/

Zoekt naar regels waarin blaat _en_ blah voorkomt.
code:
1
/(!blaat) | (blah)/

Zoekt naar die regels waar niet blaat of wel blah in voorkomt.

Voor een guide zie hier.

  • jeroen|IA
  • Registratie: Juni 1999
  • Laatst online: 26-05-2025
In plaats van een loopje te bouwen om $3 t/m NF te printen is het veel makkelijker om gewoon $1 en $2 op "" te zetten en dan de hele regel te printen met <br> appended.

Dus:
[code]
tail -n 500 | awk '/zoekterm/ {$1=""; $2=""; printf("%s<br>\n", $0)}'

Verwijderd

Nee, want dan krijg je twee spaties aan het begin van de regel.

  • jeroen|IA
  • Registratie: Juni 1999
  • Laatst online: 26-05-2025
Mja das waar. Toch is dat in HTML code niet zo'n probleem natuurlijk. Eventueel kun je het doen met een kleine workaround:

tail -n 500 | awk '{$1=""; $2=""; sub(/^ */, ""); printf("%s<br>\n", $0)}'

Nog altijd korter :P

Verwijderd

Topicstarter
als ik doe
cat /var/log/messages | awk /mark/

krijg ik output.

Maar als ik doe
cat /var/log/messages | awk /(mark) | (warn)/
zegt ie "bash: syntax error near unexpected token '/(m'

Verwijderd

Topicstarter
tail -n 500 | awk '{$1=""; $2=""; sub(/^ */, ""); printf("%s<br>\n", $0)}'

bij mij geeft

cat localmessages | awk '/(Hex:) | (cisco)/ {printf("%s<br>\n,$0")}'


de volgende error

awk: cmd. line:1: (FILENAME=- FNR=4) fatal: not enough arguments to satisfy format string
`%s<br>
,$0'
^ ran out for this one

??

Verwijderd

Op donderdag 06 december 2001 14:34 schreef jeroen het volgende:

Mja das waar. Toch is dat in HTML code niet zo'n probleem natuurlijk. Eventueel kun je het doen met een kleine workaround:



tail -n 500 | awk '{$1=""; $2=""; sub(/^ */, ""); printf("%s<br>\n", $0)}'



Nog altijd korter :P
lol... Ja zo werktie goed, en niet alleen korter maar ook sneller bij het verwerken van grote bestanden.
cat localmessages | awk '/(Hex:) | (cisco)/ {printf("%s<br>\n,$0")}'
Als je dit ingeeft, maak je een fout, namelijk de " moet achter \n en niet achter $0.
De andere voorbeelden die je aangeeft moet eigenlijk wel werken, als ik ze copy/paste dan werken ze bij mij.

  • Mx. Alba
  • Registratie: Augustus 2001
  • Laatst online: 22:04

Mx. Alba

hen/hun/die/diens

En inderdaad maken extra spaties niet uit - het is immers toch HTML... :)

awk heb ik me eigenlijk nooit erg in verdiept. Lijkt wat op een versimpelde Perl... Of trap ik nu op een heleboel tenen? :)

Het is alleen een echte hetze als het uit Hetzerath komt, anders is het gewoon sprankelende ophef.


Verwijderd

Geen idee, werk niet met Perl.

  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 00:35

odysseus

Debian GNU/Linux Sid

Op donderdag 06 december 2001 15:39 schreef hermanb het volgende:
Maar als ik doe
cat /var/log/messages | awk /(mark) | (warn)/
zegt ie "bash: syntax error near unexpected token '/(m'
Je moet de awk-expressie tussen '' zetten.
Lijkt wat op een versimpelde Perl... Of trap ik nu op een heleboel tenen? :)
Ja, lijkt er zo te zien inderdaad erg op. Maar toch heb ik nog veel liever perl ;) . Die kan bij mijn weten nog veel meer met regexps. Of kan awk ook al iets als $string =~ s/test(?=\s)/test2/gi? Dus wel kijken of iets ergens voorkomt, maar het niet meenemen in de uiteindelijke string? Heb me er zelf niet zo in verdiept, meestal gebruik ik sed voor dergelijke klusjes.

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


  • Mx. Alba
  • Registratie: Augustus 2001
  • Laatst online: 22:04

Mx. Alba

hen/hun/die/diens

Op donderdag 06 december 2001 19:04 schreef KrunK het volgende:
Geen idee, werk niet met Perl.
Perl is een uit de klauwen gelopen scripttaal. Het is gemaakt door iemand die grote hoeveelheden usenetberichten wilde filteren, en dat met grep en awk niet lukte. Hij maakte toen een scripttaal die dat wel kon, en van daaruit is Per]l gegroeid. En geëvolueerd. En gegroeid. En geëvolueerd. En nog verder gegroeid. En het groeit nog steeds.

De filosofie achter Perl is om alles toe te staan. Het klaagt nooit, geeft geen waarschuwingen, en geeft alleen errors als het daadwerkelijk crasht.

Je kent vast wel dat lijstje van hoe je je met verschillende programmeertalen in je voet kunt schieten? Met Perl kan je een nuke op je voet gooien, en daarna loop je nog steeds door :)

Perl is er trouwens wel berucht om dat het te makkelijk is om "write only code" te maken. Code die je in elkaar flanst, die werkt, maar die je daarna niet meer kunt lezen...

Dit bijvoorbeeld is een heerlijk stukje Perl dat dienst doet als signature:
code:
1
2
3
4
@P=split//,".URRUU\c8R";@d=split//,"\nrekcah xinU / lreP rehtona tsuJ";sub p{
@p{"r$p","u$p"}=(P,P);pipe"r$p","u$p";++$p;($q*=2)+=$f=!fork;map{$P=$P[$f^ord
($p{$_})&6];$p{$_}=/ ^$P/ix?$P:close$_}keys%p}p;p;p;p;p;map{$p{$_}=~/^[P.]/&&
close$_}%p;wait until$?;map{/^r/&&<$_>}%p;$_=$d[$q];sleep rand(2)if/\S/;print

Dat stukkie kreeg trouwens de tweede prijs in een "obfuscated Perl contest" :+

[edit]
oooOOooOoOOOOOoooo... Nog een mooier stukkie Perl gevonden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
/;{}def/#{def}def/$_={/Times-Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$
;/q{exch}#/x ; {/J q #}#/.{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup
260 40 moveto 90 rotate ; %/}};$0='"\e[7m \e[0m"';@ARGV=split//,reverse 
q(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ;
 ; $_= q /m$ pop T($*!$"=!$ " )pop " * true% ? $ " $!" "  !!  !! % !" !"    !
! charpath {!"""}pop $ pop{""!}pop ! neg{!#}pop 220 ! neg _{!!}pop J false %T
charpath  clip " pop 0 " moveto 6{!!}pop $_= 105{!!}pop {$ ! $ " !  #! ##}
pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} pop
neg{!#! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop  _ pop{"}pop } repeat pop
" {  $ " ! ! ! $ " ! !" "#"  #"!"""""! #" " # "m/;@ARGV=(@ARGV[-14..-1])x50;q}
 0 "%};s/m[ou]|[-\dA-ln-z.\n_{}]|\$_=//gx;s/(.)(?{$*=''})/('$*.='.(++$#
%2?'':"$0;").'pop;')x(ord($1)-31).'$*'/gee;s/((.(\e\\[.m)*|.){77})/$1\n/g;print
; sub showpage {}

Is ook geldig PostSrcript, naar het schijnt... Eens kijken wat het print :)

Het is alleen een echte hetze als het uit Hetzerath komt, anders is het gewoon sprankelende ophef.


  • odysseus
  • Registratie: Augustus 2000
  • Laatst online: 00:35

odysseus

Debian GNU/Linux Sid

Je kunt nog veel meer leuke dingen met perl hoor...wat dacht je van deze:
$b='$b=%c%s%c;printf$b,39,$b,39;';printf$b,39,$b,39;
Dit is bij mijn weten de kortst mogelijke manier om in perl een programma te schrijven wat precies zijn sourcecode uitspuugt. Mocht er iemand tijd hebben dan mag hij iets beters verzinnen ;) . En niet spieken op http://www.nyx.net/~gthompso/self_perl.txt ...

...En tot zover mijn off-topic reacties in deze thread :)

Leven is het meervoud van lef | In order to make an apple pie from scratch, you must first create the universe.


Verwijderd

Topicstarter
wel een gevoelig taaltje zeg.

/(ppp0) /
is niet hetzlefde als
/(ppp0)/
sjonge. Maar werk wel precies prima voor wat ik wil.

Alleen is het niet
/(!blaat)/
maar
!/blaat/

maar goed:-)

Verwijderd

Ja klopt daar kom ik nu ook achter.
Pagina: 1