Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: Boss321 25. 03. 2010, 16:57:18

Název: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 25. 03. 2010, 16:57:18
zdravím mám takový problém, řeším takovou úlohu, ale nějak to furt nemůžu doladit.

Chci udělat skript, který pomocí filtru awk (jedním vyvoláním) vypíše z „ypcat passwd“ celé záznamy vybraných uživatelů s uvedenými úpravami:
1. Vybere všechny uživatele s UID <= 30000 nebo jejichž uživatelské jméno neodpovídá vzoru „ppppppn“, kde p je písmeno a n je číslice.

ypcat passwd | awk -F: '$3<=30000 || $1 !~ /[a-zA-Z]\{6\}[1-9]/' - tohle funguje bez problému

2. U těchto vybraných, jestliže uživatelské jméno neodpovídá vzoru „ppppppn“, prohodí v cestě k domovskému adresáři první 2 jména (např. /home/Blabla/.... -> /Blabla/home/........) a výsledný záznam vypíše, jinak vybraný záznam vypíše beze změny.

ypcat passwd | awk -F:  '/\(.*\):\/home\/.*\/\(^[a-zA-Z]\{6\}[1-9])/\1:\/.*\/home\/\2/' {print $0} .... nevíte někdo, kde dělám chybku?       

Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: bseller.eu 25. 03. 2010, 17:12:00
motate do sebe awk a sed. Pokud si najdu chvilku odpovim presneji.
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 25. 03. 2010, 17:35:48
Aha, já jsem právě v shellu celkem začátečník a vůbec si s tímhle nevím rady, tak kdybyste jste si našel chvilku, tak bych Vám byl moc vděčný.
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 25. 03. 2010, 19:58:53
Už se tomu alespoň přibližuji?

ypcat passwd | awk -F: '$1 !~ /[a-zA-Z]\{6\}[1-9]/ { print $1,$2,$3,$4,$5,''{FS="/"} {$2,$1}'',$7 } '

Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: bseller.eu 25. 03. 2010, 20:10:51
myslim, ze neni mozne zmenit field separator v jednom radku. Reseni jsem ale nasel:
1. do souboru tmp.sed dat substitucni regexp
/\(.*\):\/home\/.*\/\(^[a-zA-Z]\{6\}[1-9])/\1:\/.*\/home\/\2/
2.volat sed z awk a to nejak takto
awk -F: '$3>=1000 {print $0 | "sed -f tmp.sed"} $3<1000 {print $0}'
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: wamba 25. 03. 2010, 20:15:09
pro inspiraci pomocí perlu by to šlo třeba takto
Kód: [Vybrat]
cat /etc/passwd|perl -F":" -ane '($F[0] !~ /^[A-Za-z]{6}\d$/ &&  $F[5] =~ s{/(.*?)/([^/]*)}{/$2/$1}   || $F[2] <= 30000) && print join ":",@F'
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 25. 03. 2010, 20:37:53
A nebylo by možné to řešení, nějak upravit, aby to bylo bez souboru??
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: bseller.eu 25. 03. 2010, 20:47:23
pokud se Vám podaří toto rozběhat tak proč ne. Pokud byste zjistil jak na problém "uvozovek v uvozovkách" tak dejdte prosím vědět
 cat /etc/passwd | awk -F: '$3>=1000 {print $0 | "sed -e s/\(\.*\)\/home\(\/.*\)\(\/.*\)/\1\2\/home\3/""} $3<1000 {print $0}'
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: deadmail 25. 03. 2010, 21:34:31
volat sed z awku je uplne zbytocne, awk toho vie ovela viac ...


Kód: [Vybrat]
cat /etc/passwd | awk 'BEGIN{FS=":";OFS=":"}
{if ($3 <= 3000) {$6=gensub(/\home\/([^/]*)/, "\\1/home", "g", $6)}; print}'
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 26. 03. 2010, 07:52:47
děkuji moc, ale když příkaz zadám do shellu, tak mi to neustále píše syntax error.
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: bseller.eu 26. 03. 2010, 07:58:17
gensub jsem v awk neznal, díky!
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 26. 03. 2010, 08:32:17
Prosím Vás ještě bych měl poslední dotaz, když po těchto dvou úpravách mám: počet nalezených řádků a počet provedených záměn.

Tak řádky zjistím awk 'END { print "Pocet radku je: " NR}'

ale nevím, jak zjistím počet záměn?
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: deadmail 26. 03. 2010, 08:32:50
Citace
děkuji moc, ale když příkaz zadám do shellu, tak mi to neustále píše syntax error.

mne to to ziadnu chybu nepise (v bashi) - treba poslat chybu, ale chybali tam este lomitka:

Kód: [Vybrat]
cat /etc/passwd | awk 'BEGIN{OFS=FS=":"} {if ($3 <= 3000) {$6=gensub(/\/home\/([^/]*)/, "/\\1/home", "g", $6)}; print}'
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 26. 03. 2010, 08:38:23
Já mám také bash a píše mi to tohle:

cat /etc/passwd | awk 'BEGIN{OFS=FS=":"} {if ($3 <=3000) {$6=gensub(/\/home\/([^/]*)/, "/\\1/home", "g", $6)}; print}'
awk: syntax error near line 1
awk: illegal statement near line 1
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: deadmail 26. 03. 2010, 09:33:03
Kód: [Vybrat]
awk --version
V GNU Awk 3.1.6 to funguje.

Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 26. 03. 2010, 09:43:32
Dobrá já si s tím nějak pohraji........a chtěl jsem se zeptat jak udělám abych navázal na můj skript:
ypcat passwd | awk -F: '$3<=30000 || $1 !~ /[a-zA-Z]\{6\}[1-9]/'
který mi vybere z ypcat uživatele s UID<=30000 nebo uživatele, kterým neodpovídá vzor, tím Váším, který z tohoto výpisu má pomocí toho vašeho skriptu, u těch uživatelů, kteří neodpovídají vzoru, tak prohodit tu cestu. A na závěr bych měl spočítat řádky, což udělám přes
 awk 'END { print "Pocet radku je: " NR}'
a ještě bych měl spočít celkový počet záměn, ale to vůbec nevím jak se udělá??
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: deadmail 26. 03. 2010, 17:49:27
Dobrá já si s tím nějak pohraji........a chtěl jsem se zeptat jak udělám abych navázal na můj skript, který mi vybere z ypcat uživatele s UID<=30000 nebo uživatele, kterým neodpovídá vzor, tím Váším, který z tohoto výpisu má pomocí toho vašeho skriptu, u těch uživatelů, kteří neodpovídají vzoru, tak prohodit tu cestu. A na závěr bych měl spočítat řádky a ještě bych měl spočít celkový počet záměn, ale to vůbec nevím jak se udělá??

Nejako takto
Kód: [Vybrat]
cat /etc/passwd | awk 'BEGIN {OFS=FS=":"; pocet=0}
($3<=30000) || ($1 !~ /[a-zA-Z]\{6\}[1-9]/) {if ($6 ~ "^/home/") {$6=gensub("/home/([^/]+)", "/\\1/home", "", $6);pocet++}; print}
END {print "Pocet radku je: " NR; print "Pocet zamen: " pocet}'
?
Název: Re: Skriptík v shellu pomocí awk
Přispěvatel: Boss321 26. 03. 2010, 20:00:23
Ano, perfektní, děkuji Vám moc!