Van ez a parancs:
awk '/privvmpages/ {print $6}' /proc/user_beancounters
Alapvetően jól működik - nem meglepő, mert nem túl bonyolult -, de mivel sok konténeren, sokszor, sok paraméterre kell lefutnia, ezért érdekelne, hogy van-e valami az awk helyett, ami kevesebb erőforrást eszik, kevesebb libet tölt be, meg egyáltalán.
A beancounters (ha valakinél nincs kéznél):
Version: 2.5
uid resource held maxheld barrier limit failcnt
141: kmemsize 6124602 8218054 218060400 218060400 0
lockedpages 0 4161 256 256 45
privvmpages 46060 89367 521151 573266 0
shmpages 4410 4411 294861 294861 0
dummy 0 0 0 0 0
numproc 26 37 240 240 0
physpages 26407 42805 0 9223372036854775807 0
vmguarpages 0 0 294861 294861 0
oomguarpages 26407 42805 521151 521151 0
numtcpsock 11 26 360 360 0
numflock 2 9 188 206 0
numpty 1 2 16 16 0
numsiginfo 0 9 256 256 0
tcpsndbuf 204920 1336472 1720320 2703360 0
tcprcvbuf 180224 219200 1720320 2703360 0
othersockbuf 0 49944 1126080 2097152 0
dgramrcvbuf 0 2312 262144 262144 0
numothersock 41 53 360 360 0
dcachesize 169353 260648 3409920 3624960 0
numfile 523 1143 9312 9312 0
dummy 0 0 0 0 0
dummy 0 0 0 0 0
dummy 0 0 0 0 0
numiptent 27 27 128 128 0
És a strace -c nálam:
strace -c awk '/privvmpages/ {print $6}' /proc/user_beancounters
0
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
-nan 0.000000 0 4 read
-nan 0.000000 0 1 write
-nan 0.000000 0 4 open
-nan 0.000000 0 6 close
-nan 0.000000 0 4 fstat
-nan 0.000000 0 11 mmap
-nan 0.000000 0 5 mprotect
-nan 0.000000 0 2 munmap
-nan 0.000000 0 3 brk
-nan 0.000000 0 1 1 ioctl
-nan 0.000000 0 4 4 access
-nan 0.000000 0 1 execve
-nan 0.000000 0 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.000000 47 5 total
A felhasználható eszközök azok, amik a legalapabb debian telepítésben benne vannak.
Fontos, hogy a parancsot a zabbix hívja meg, tehát nem az a cél hogy egy scripten belül lefutva legyen a legkisebb a terhelés, így a shell belső parancsok kiesnek, mert arra tippelek, hogy egy shellt már betölteni is több nyomor mint az awk-ot. De ez csak tipp.
Most megyek mosogatni, addig hátha beugrik valami. Eddig a grep -o és a sed jutott az eszembe.
- 9866 megtekintés
Hozzászólások
Esetleg egy kisebb awk, ha létezik a jelenleginél kisebb. (ha gawk van felrakva, akkor a mawk szóba jöhet)
A grep-nek hogy adod meg, hogy csak a megfelelő mezőt írja ki?
A -o a teljes illeszkedő mintát kirakja, nem csak a numerikus részét. Vagy az nem gond?
Akit tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
De, épp ez a gond, de hátha valaki, aki nálam jobbam ért hozzá, tud valamit :D
- A hozzászóláshoz be kell jelentkezni
Ubuntu 12.04 64bit:
awk 92 call, mawk 48.
Ha ez számít.
A te fájlod nálam nem létezik, helyette a /proc/meminfo egy sorát választottam a próbához.
Viszont elnézve az strace-ed kimenetét, nálad is valami mawk v. hasonló lehet fenn. Ennél (nálam) az összes többi módszer rosszabb eredményt hozott, ha rendszerhívások számát nézzük.
uodate: találtam egy működő debiant. A mawk a default, ennél kisebbet nem nagyon találsz, azt hiszem.
Akit tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Kicsit nézegetve a számokat arra jutottam, hogy először is gondolkozni kellett volna, mert sokkal lejjebb úgyse lehet vinni az értékeket.
- A hozzászóláshoz be kell jelentkezni
Ezt így nem mertem kijelenteni, mert mittudomén hol tart már a tudomány... ;) De kb. így gondolom én is.
Egyébként honnan jött egyáltalán az ötlet?
Miért akarsz ezen még gyorsítani?
Akit tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
Az ötlet onnét, hogy tapasztaltam, hogy néha meglepő trükköket lehet csinálni olyan parancsokkal, amikre magamtól nem is gondoltam volna.
Az optimalizációnak nem a gyorsítás a legfőbb célja, hanem az erőforrás-felhasználás minimalizálása, mert ezek a parancsok sokszor fognak lefutni, párhuzamosan, több konténerben, szinte egyszerre, és nem akarom, hogy egy esetleg terhelt rendszert ez vigye a halálba :D
- A hozzászóláshoz be kell jelentkezni
A grep mellé még kell egy cut is, és akkor már nem biztos, hogy megéri. Másrészt, ha a fájlban az elválasztó karakter szóköz, akkor sajnos nem is jó a cut.
Kiegészítés:
Sőt, nálam is (crunchbang) a grep önmagában „költségesebb” mint az mawk. A gawk-nál viszont jobb.
-----
A kockás zakók és a mellészabások tekintetében kérdezze meg úri szabóját.
- A hozzászóláshoz be kell jelentkezni
Beteg ötlet?
Lefuttatni minden sorát a /proc/user_beancounters-nek? error elnyomni.
Aminek meg kell a kimenete létrehozni egy pl egy sh-t ami kiírja a megfelelő paramétert?
Nem szerverre való gondolom, de hátaha ;)
- A hozzászóláshoz be kell jelentkezni
Azon túl hogy embertelen kitolás azzal, aki nem ismeri ezt a trükköt, az erőforrásigénye kb. egy nagyságrenddel nagyobb. A legjobb esetben is :D
- A hozzászóláshoz be kell jelentkezni
Nem szorosan a Te problémádra megoldás de másokat is foglalkoztat hasonló dolog. Ill. vannak munin pluginek is amik ezeket az adatokat gyűjtik. A fenti megoldásokat nem néztem végig, de háta van közöttük olyan ami segíthet, ötletet adhat.
- A hozzászóláshoz be kell jelentkezni
Ennél egyszerűbben aligha lehetne megoldani, és ha mawk az az awk*, akkor gyorsabban se.
Illetve igen: megírod C-ben. Te tudod, hogy tényleg fut-e majd annyiszor, hogy megérje az ezzel töltött idő, másfelől viszont max. 20 sor a C változat, amit teszteléssel együtt 1 óra alatt össze lehet hozni.
*: mostanában előkerült ez a $munkahelyen: a mawk konzisztensen 2-5× gyorsabb volt a gawknál, cserébe előfordult, hogy elvileg portolható programnál sem viselkedett úgy, ahogy kellett volna.
- A hozzászóláshoz be kell jelentkezni
Igen, ez az amire gondoltam még, hogy C-ben megírom, de ahhoz meg nincs kedvem :D
- A hozzászóláshoz be kell jelentkezni
Pedig ez lenne az igazi. De ha C helyett más kedvenc nyelved van, ami compileres, azzal is valószínűleg sokkal gyorsabban futó binárist állíthatsz elő, mint az awk-s verzió. Úgyhogy akár FORTRAN is jó lehet. :-)
- A hozzászóláshoz be kell jelentkezni
Azt kell mondjam, hogy ezen sokat lehet gyorsítani - bár tisztában vagyok vele, hogy a bázis elég kicsi ahhoz, hogy a változás felszín alatt maradjon.
1.
Meg kéne adni, hogy hol található a keresett kifejezés.
Akár a
$1 == "privvmpages"
akár a
/^[[:space:]]+privvmpages/
vagy a
/^(a megfelelő mennyiségű szóköz ide leszámolva)+privvmpages/
megteszi. Érzésem szerint az első gyorsabb, de mind veri azt az esetet, amikor az egész regexppel végig kell túrni az egész sort.
2.
Ha sokszor fog futni, akkor nem biztos, hogy sokszor érdemes meghívni.
A getline ciklusba szervezésével (a close()-ról sem megfeledkezve) összehozható egy, az auto beolvasási mechanizmussal megegyező folyaamat. Már csak időzíteni kell. Nincs mese, erre a system("sleep N") adódik a legkevésbé duhajkodó eszköznek.
- A hozzászóláshoz be kell jelentkezni
1.: igen, erről meg szoktam feledkezni, bár valóban, a jelen esetben aligha van különbség
2.: ez nem az én választásom, a monitoring szerver ledob egy system.run kérést az agentnek (az most kb. midegy hogy hogy), és ebből lesz a cserebogár. Az adott gépen fut N darab konténer, konténerenként M darab figyelt értékkel, amik jó részét az agent tudja magától. Igyekszem a system.run számát alacsonyan tartani.
Normál körülmények között amúgy ez a megoldás nem okoz észrevehető terhelést, de már láttam terhelés alatt vidáman futkosó gépet kicsivel (néha sokkal :D) nagyobb terheléstől leroskadni. Nomeg felmerült bennem hogy íme a remek alkalom új dolgokat tanulni.
- A hozzászóláshoz be kell jelentkezni
Esetleg még olyat lehetne, hogy a konténeren kívül az összes VZ értékét meg tudod nézni egy cat /proc/user_beancounters -el és minden hostról el tudod küldeni az adatokat a monitoring szervernek passive checkként (nagiosnál, máshol lehet máshogy hívják, de szerintem támogatott).
- A hozzászóláshoz be kell jelentkezni
Ez volt az eredeti terv :D
Sajnos felmerültek problémák, a zabbix nem fogad el nem létező hostra nem létező itemeket, mert hová is tenné. Ezért aztán kalapálnom kellett egy scriptet ami a zabbix api-t használva felveszi a hostokhoz az itemeket, triggereket, miegyebeket. A template nem jó, mert egy hostra kellett felvenni az összes konténer adatait. Mire ez megírtam meg minden, úgy döntöttem, hogy akkora gányolás, hogy inkább nem (marha macerás karbantartani, új host, item, trigger, graph esetén megfelelően frissíteni, rajtam kívül senki nem tud érdemben hozzányúlni, sőt, egy év múlva már én se, ehe, stb. stb.).
Az utolsó szöget a koporsóba asszem a vzquota verte, amit megint másképp kell kezelni, és úgy döntöttem, hogy fusson az a nyomorult agent, nem eszik sok erőforrást, és többet ésszel, mint erővel, alacsonyan tartom a monitorozott értékek számát valamit a mintavétel frekvenciáját.
Most automata discovery van, ha felpattintok egy konténert, benne egy agenttel, akkor öröm van és boldogság.
- A hozzászóláshoz be kell jelentkezni
Lehet valamit rosszul nézek, de én grep-pel kevesebb hívást kapok.
strace -c awk '/MemFree/ {print $2}' /proc/meminfo
calls / errors = 92 / 7
strace -c grep MemFree /proc/meminfo | grep -oE "[0-9]+"
calls / errors = 60 / 8
Ja bocs, egyrészt mawk-kal nálam is 47 hívás, másrészt most látom hogy több numerikus oszlop van, azt már drága lenne kikapni - kivéve ha az utolsó szám kell.
- A hozzászóláshoz be kell jelentkezni
Egyrészt kellhet másik oszlop, másrészt te csak az első grep-et számolod :D
- A hozzászóláshoz be kell jelentkezni
strace mutatja a lib betolteseket is, kezdve pl. az /etc/ld.so.conf -fal.
Forditsd statikus awk-ot, ha zavar, az lejjebb viszi.
Masik lehetoseg folyamatos awk invokalas helyett egy folyamatosan futo processzt csinalni. gawk pl. tud getline-t, rakd bele egy '{while(1)}' ciklusba es jo vagy.
Vagy ha mar ugyis egy shell script fut, miert nem csinalod bash-ban? pl.
while read -a A; do
echo $A[6]
done </proc/user_beancounters
man bash, v4.1 - v4.2 korul igen tapos boviteseket kapott am!
- A hozzászóláshoz be kell jelentkezni
Ezeket ismerem, de mint írtam _nem_ shellscriptről van szó, és egy bash-t feltekerni jóval több erőforrás mint az awk. Gondolom én.
- A hozzászóláshoz be kell jelentkezni
Persze, hogy tobb. De valamibol az awk-ot is inditod, nemde? Marpedig ha mar ott fut az a bash, amiben a gawk commandline-t hajtod vegre, akar csinalhatna az is a melot :)
- A hozzászóláshoz be kell jelentkezni
"Fontos, hogy a parancsot a zabbix hívja meg, tehát nem az a cél hogy egy scripten belül lefutva legyen a legkisebb a terhelés, így a shell belső parancsok kiesnek"
Direkt ezért írtam le.
- A hozzászóláshoz be kell jelentkezni
Akkor marad a cut.
cut -d80- /proc/user_beanblabla
odaadja neked a 80. oszloptol minden sort. Hatranya, hogy a space-ek is ott maradnak az elejen, de azt valszeg ez a zabbix lekezeli.
De megintcsak, a strace szerint a teljesitmeny jo resze az ld-ben veszik el, azon meg csak a statikus forditas segit.
BTW, egesz biztos vagy abban, hogy a zabbix a parancsot nem egy shell-ben futtatja? Mert gyakori, hogy ilyet trukkoznek, hogy a kezdo sysadminoknak is mukodjon a a shell-style stdin/stdout redirect.
- A hozzászóláshoz be kell jelentkezni
Majdnem rávágtam hogy igen (nekem úgy tűnt értelmesnek :D), de kipróbáltam, és nem. /bin/sh -c futtatja a parancsokat.
- A hozzászóláshoz be kell jelentkezni
Akkor egyszeru, siman pakold a fenti while ciklust az sh -c parancssoraba. Nekem itt ubuntu-n megy, de a bubi a /bin/sh -t dash-sel csinalja.
Apropo, dash: kevesebb fuggosege van, emiatt gyorsabb a startup. Van viszont debianban is sash, standalone shell, ami statikusan van forditva. Valszeg ennek a legkisebb az overhead-je. Ha atallitod a /bin/sh -t erre (amugy is jo otlet, ha beut a krach, nem kell libekkel tokolni alapveto funkciokhoz), es a parancsnak egy while loop-ot adsz meg, pl. igy:
sh -c 'while read i; do echo $i; done' </etc/passwd
Akkor mar jo lesz szerintem.
- A hozzászóláshoz be kell jelentkezni
Erosen ketlem, hogy egy statikus sh inditasa valamikor egy mukodo rendszer kellos kozepen kisebb overhead lenne, mint egy dinamikus inditasa. Ugyanis a dinamikusnak mar kb 80%-a benn van a memoriaban, es az adminisztracioval kell (szinten a memoriaban) molyolni, mig ugyanannak a shell-nek a statikus verziojanal az egesz binarist be kell huzni.
- A hozzászóláshoz be kell jelentkezni
A statikusnak meg 100%-a van memoriaban. Egy processz inditasa ugy kezdodik, hogy mmap() -olja a binarist, es a kernel eleg okos ahhoz, hogy ujra felhasznalja a processzek kozott az mmap()-olt page-eket.
Ellenben a dinamikusnak bejatszik minden egyes inditasnal a linkeles, ahhoz meg konfig file-ok olvasgatasa, parse-olasa, stb...
- A hozzászóláshoz be kell jelentkezni
Marmint akkor van a memoriaban, ha valamikor korabban mar egyszer legalabb elinditottak. De a tobbseg nem /bin/sash, hanem /bin/sh-t tartalmaz a shebang sorban, szoval kerdeses.
- A hozzászóláshoz be kell jelentkezni
Najó, de ezzel nem megyek semmire.
Először is az sh -c kiesik, mert akkor a végletes parancs sh -c "sh -c 'blabla'" lenne.
Másodszor ha while-read, akkor vagy grep soronként meghívva és utána cut (sokszoros erőforrás) vagy valami bash-dash-sh (only?) trükk, amivel a szövegfájl feldolgozható.
Esetleges megoldás lenne egy sh kompatibilis sor, ami külső parancsok nélkül végez mintaillesztést és stringvágást. A bash ugye tud olyat, hogy ${parameter/pattern/string}, ezzel esetleg lehetne operálni, de egyrészt semmi se garantálja hogy a /bin/sh az bash (és amúgy se az szerintem), illetve továbbra is adott a sorok olvasása a probléma, a read-while nálam riasztóan sok call-t dob.
Mókás, hogy a dash 1546 call-t hív, a bash 269-et, nálam:
strace -c /bin/bash -c 'while read i ; do echo $i ; done < /etc/passwd'
strace -c /bin/dash -c 'while read i ; do echo $i ; done < /etc/passwd'
- A hozzászóláshoz be kell jelentkezni
Teljesen standard mintaillesztes sh-ban
a) case, hatulutoje, hogy nem regexp-et, hanem shell globbingot hasznal
b) modernebb shellekben a [[ sztring == minta ]] formaval is lehet, szinten globbing van regexp helyett
sztringvagas ${valtozo#glob} vagy ${valtozo%glob} (illetve ## es %% formaban) - ez es az a) pont teljesen elterjedt, mindegy h bash/dash/ash/zsh anyamkinja. (De ez itt mar nagyon offtopic)
- A hozzászóláshoz be kell jelentkezni
ls -la | sh -c 'while read a b c d e f g; do echo $f; done'
(sajnos sh nem ismeri a 'read -a' -t, ezert a fenti trukkozes)
bash eleg effektiv interpreter, nem csodalom, hogy jobban optimalizal, mint a dash.
Viszont nagy elony, hogy nem kell awk-ot inditani, zubbix shelljebol megoldhato a dolog.
- A hozzászóláshoz be kell jelentkezni
Igen, erre gondolhattam volna (ha nem használtam ezt százszor, akkor egyszer se, ehe), de sajnos úgy tűnik, hogy ez a drágább megoldás:
strace -c /bin/dash -c 'while read a b c d e f; do if [ $a = privvmpages ] ; then echo $f ; fi ; done < /proc/user_beancounters'
3312 syscall
strace -c /bin/dash -c 'echo ok'
negyven syscall, így a dash bő 3000 sycall-t lő el. Tippre karakterenként olvas, ami elég elkeserítő. Az awk még mindig bőven vezet, a
strace -c /bin/dash -c "/bin/echo ok"
42 syscall plusz a
strace -c awk '/privvmpages/ {print $6}' /proc/user_beancounters
47 syscall, összesen 89.
Ha match esetén dobok egy exit 0-t, akkor a dash read-if lemegy 500-ra kb, de ugye ha a file végén van az egyezés, akkor ez se ér sokat.
Persze az egyes hívások nem egyelő terhelést adnak, de ez alapján még úgy néz ki, hogy az awk a nyerő. Persze jó kérdés, hogy maga az awk betuszkolása az tulajdonképp mekkora overhead a dash karakterenkénti olvasásával szemben.
Viszont elkezdtem azon merengeni, hogy nagy load esetén leállok pár érték (vagy a teljes konténer) monitorozásával, de ezt még átgondolom. Alighanem számolatlanul vannak még fontosabb dolgok :D
- A hozzászóláshoz be kell jelentkezni
Lehet, hogy egy nagy hülyeséget írok, de vagy 10 évvel ezelőtt olvastam olyanról, hogy root jogokkal be lehet állítani, hogy bizonyos fájlok mindig a RAM-ban tárolt pufferben legyenek, onnan ne söpörje ki őket a kernel. Talán ha az awk és a hívott lib-ek ilyen módon lennének tárolva, akkor sosem kellene a merevlemezhez fordulni indításukkor, ami takaríthat meg időt. Persze, ha sűrűn vannak hívogatva, úgysem ürülnek ki a pufferből, úgyhogy nem biztos, hogy ez jó ötlet.
- A hozzászóláshoz be kell jelentkezni
Nem hiszem hogy kiürülnének a pufferből. Egy dstat-al simán ellenőrizheted. Nekem hozzá sem nyúl a lemezhez parancssorban dolgozás során.
- A hozzászóláshoz be kell jelentkezni
OK, nem ismerem ott a RAM-méretet, az awk hívások közti IO-műveletek mennyiségét, stb, ami befolyásolja, hogy két ilyen hívás közt kiürül-e az awk a pufferből. Persze, ha sűrűn hívódik, vagy közben kevés az IO, akkor magától is bennmarad.
- A hozzászóláshoz be kell jelentkezni
Mondjuk igazad van, valóban lehet olyan művelet ami kiüríti az egész puffert.
- A hozzászóláshoz be kell jelentkezni
Szerintem az egy kicsit más volt.
Emlékeim szerint - és lehet hogy ez is balgaság - pl. a libeket nem tölti be minden egyes alkalommal a loader, hanem csak egy pointert bök rá, ha már az a ramban van. Nem tudom hogy a libekhez tartozhat-e adatszegmens, esetleg ahhoz kellhet külön művelet.
Hasonló megoldás rémlik a végrehajthaó binárisokkal kapcsolatban is.
- A hozzászóláshoz be kell jelentkezni
Most a sticky-bitről beszélsz? Vagy az mlock(2)/mlockall(2) -ról?
- A hozzászóláshoz be kell jelentkezni
Az mlock-kal kevertem, bocs. Az persze itt nem használható.
Amiről írtam, arra tényleg nincs ilyen megoldás, csak rosszul emlékeztem. Ha bármit is számítana az awk és a libek betöltési ideje, akkor azokar RAM-diskre kellene kitenni, de ez egy hülye erőltetett megoldás lenne, ami feltehetően keveset hoz a konyhára.
[De legalább jól sejtettem, hogy félrebeszélek. :-) ]
- A hozzászóláshoz be kell jelentkezni
De van, csak az op.rendszert úgy hívják, hogy OpenVMS :)
Akit tudja, csinálja, aki nem tudja, tanítja... Hm... igazgatónak talán még jó lennék. :)
- A hozzászóláshoz be kell jelentkezni
miert akarsz egy merhetetlen ideju taskot "optimalizalni"?
--
NetBSD - Simplicity is prerequisite for reliability
- A hozzászóláshoz be kell jelentkezni
N*M példányban fog futni, ahol az N a konténerek, az M az itemek száma, nem megbecsülhető párhuzamossággal, ami egy és végletes esetben akár párszáz is lehet.
- A hozzászóláshoz be kell jelentkezni
// fawk.c : minimalist awk
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
//returns index of a non-nul terminated substring within a non-nul terminated string
int str_idx(char* str, int str_len, char* substr, int substr_len)
{
char* orig_str = str;
while( substr_len <= str_len )
{
int i;
for(i=0; i<substr_len; ++i)
{
if( str[i] != substr[i] )
break;
}
if( i == substr_len )
return str - orig_str;
--str_len;
++str;
}
return -1;
}
int usage(int ret_code)
{
printf(
"usage: fawk <pattern> <column # to print> <input> [options]\n"
"where\n"
" <pattern> a word in quotes to search for in the columns - no regexp allowed\n"
" <column # to print> serial of word to be printed\n"
" <input> input file to read\n"
" options:\n"
" --first_match_only stops searching after the first match\n"
" --substring_match the word is used as substring (default=exact match)\n"
"\n"
"example: fawk \"privvmpages\" 6 /proc/user_beancounters \n"
);
return ret_code;
}
int main(int argc, char* argv[])
{
FILE* fi;
int i;
char line[4096+1];
char* endp;
int column_to_output;
char* word_to_search_for;
size_t word_to_search_len;
int first_match_only = 0;
int substring_match = 0;
if( argc < 3 ) {
printf("error: improper number of parameters\n");
return usage(1);
}
word_to_search_for = argv[1];
word_to_search_len = strlen(word_to_search_for);
if( word_to_search_len <= 0 ) {
printf("error: invalid word to search for: '%s'\n", argv[1]);
return usage(2);
}
column_to_output = strtoul(argv[2], &endp, 10);
if( endp == argv[2] || column_to_output < 0 ) {
printf("error: invalid column number: '%s'\n", argv[2]);
return usage(3);
}
for(i=4; i < argc; ++i)
{
if( strcmp(argv[i], "--first_match_only")==0 )
first_match_only = 1;
else if( strcmp(argv[i], "--substring_match")==0 )
substring_match = 1;
}
fi = fopen(argv[3], "rt");
if( !fi ) {
printf("error: could not open input file '%s'\n", argv[3]);
return usage(4);
}
while( fgets(line, sizeof(line), fi) )
{
char* p;
size_t len;
int word_num, match_found;
char* word_to_output = NULL;
size_t word_to_output_len = 0;
line[sizeof(line)-1] = '\0';
len = strlen(line);
if( len > 0 && line[len-1] == '\n' )
line[--len] = '\0';
//if 0'th column requested, this means the whole line to be outputted
if( column_to_output == 0 )
{
word_to_output = line;
word_to_output_len = len;
}
//splitting row into words; finding the specified pattern in words
match_found = 0;
word_num = 0;
p = line;
while(!match_found || word_to_output_len==0)
{
char* word_start_p;
size_t word_len;
//skip spaces before next word
while( isspace(*p) )
++p;
if( !*p )
break; //line end, no more words
//word starting char found
++word_num;
word_start_p = p++;
//find word end
while( *p && !isspace(*p) )
++p;
word_len = p - word_start_p;
//if we are at the N'th column, store the word to be outputted
if( column_to_output == word_num )
{
word_to_output = word_start_p;
word_to_output_len = word_len;
}
//check if this word matches the pattern
if( !match_found && word_to_search_len <= word_len )
{
if( substring_match )
match_found = str_idx(word_start_p, word_len, word_to_search_for, word_to_search_len) >=0;
else
match_found = strncmp(word_start_p, word_to_search_for, word_to_search_len) == 0;
}
}
if(match_found && word_to_output_len > 0)
{
printf("%s\n", word_to_output);
if( first_match_only )
break;
}
}
fclose(fi); fi = NULL;
return 0;
}
- A hozzászóláshoz be kell jelentkezni
Köszi :) Ez már ráver az awk-ra :D
- A hozzászóláshoz be kell jelentkezni
mennyivel? adatokat kérünk! :)
- A hozzászóláshoz be kell jelentkezni
40 vs. 47 :D
- A hozzászóláshoz be kell jelentkezni
Ebben van valami Linux specifikus? Pl. egy AIX -on gcc-vel le tudom fordítani vajon ?
------------------------------------------
"Nincs ez el**szva, csak másra lesz jó!"
- A hozzászóláshoz be kell jelentkezni
Ehhez kb a legbutább fordító is elég kell legyen, és nincs benne semmi OS-specifikus. De ha már terjedni akar, akkor
- minden warning/error printf( ... ) lecserélendő fprintf( stderr, ... ) -re
- meg pl. az utolsó fi=NULL ; utasítást optimalizáld ki te magad, ne bízd a fordítóra
meg lehetne még hasogatni a szőrszálakat
Szerk: ja, és szerintem copy and paste-tel együtt is hamarabb kiderült volna, ha kipróbálod, mint várni a válaszra :-)
- A hozzászóláshoz be kell jelentkezni
Nem biztos hogy épp kéznél van neki egy aix-gcc kombó :D
- A hozzászóláshoz be kell jelentkezni
Éppenséggel volt... ~700 közül akadt egy amin volt GCC :D
------------------------------------------
"Nincs ez el**szva, csak másra lesz jó!"
- A hozzászóláshoz be kell jelentkezni
BTW, goto serverfault.com ilyen kerdesekkel batran.
- A hozzászóláshoz be kell jelentkezni