Nem akartam ilyen piti problémával topicot kezdeni, de egyszerűen nem jövök rá hogy miért nem működik a scriptem...
Két fájl összehasonlítását szerettem volna megvalósítani.
Mindkét fájl hosztok neveit tartalmazza, uppercase formázva, egymás alá írva.
Valószínűleg nagyon bugyuta megoldást találtam ki :)
A lényeg, hogy soronként végigmegyek az egyik fájlon, és mindig megnézem azt, hogy az aktuális sorban található hoszt meg van-e a másik fájlban.
(az AD_hosts és zbx_hosts változók a két fájl útvonalát tartalmazzák)
AD_list_size=`cat $AD_hosts | wc -l`
i=1
for i in $(seq 1 $AD_list_size)
do
currenthost=`cat $AD_hosts | head -n $i | tail -n 1`
echo $currenthost
checkedhosts=`cat $zbx_hosts | grep $currenthost`
echo $checkedhosts
#if [ "$currenthost" == "$checkedhosts" ]
#then
#echo "AD_list:"$currenthost "Zbx_list:"$checkedhosts "Hostname is equal!"
#else
#echo "AD_list:"$currenthost "Zbx_list:"$checkedhosts "Hostname IS NOT equal!"
#fi
done
végeredményben a script ki kellene hogy írjon minden hosztnevet 2x
ehhez képest a $currenthost változó tényleg tartalmazza a hosztok neveit, de a $checkedhosts mindig üres
shellben minden működik... csak scriptben nem...
mi lehet a probléma?
egyáltalán hogyan kellene összehasonlítanom ezt a két fájlt?
Előre is köszi a segítséget!
- 11420 megtekintés
Hozzászólások
Ennel nem la'tom hogy pont ez lenne a problema, de: ha ugy kezded a szkripteded hogy #!/bin/sh, az ujabb deb-ekne'l ma'r a /bin/dash lesz es nem a /bin/bash. azaz kezdd igy hogy #!/bin/bash, ha'tha...
- A hozzászóláshoz be kell jelentkezni
Juj.
while read currenthost do
if grep -q "$currenthost" "$zbx_hosts"; then
echo "$currenthost found"
else
echo "$currenthost NOT found"
fi
done < "$AD_hosts"
Prekoncepciok:
- Mindket fajlban minden host csak egyszer szerepel
- Mindket fajlban minden host kulon sorban van
- A hostok nevei ujsor karaktert nem tartalmazhatnak
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Ebben azért megvan az a veszély, hogy ha az zbx_hosts fájl tartalmaz olyat, hogy
egy.hulye.nev
a referencialista pedig, hogy
ez.is.egy.hulye.nevecske.de.megsem.ugyanaz
akkor azt hiszi, hogy megtalálta, amit pedig nem is.
Persze fel lehet cicomázni a grepet, hogy jól csinálja, vagy akár:
awk 'FILENAME=="zbx_hosts" { zbxhosts[$1]; next }; !($1 in zbxhosts) { print $1 }' zbx_hosts AD_hosts
amire, ha jól írtam, meg kell jelennie mindennek, ami csak az AD_hostsban van.
- A hozzászóláshoz be kell jelentkezni
-if grep -q "$currenthost" "$zbx_hosts"; then
+if grep -q "^$currenthost\$" "$zbx_hosts"; then
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
sort -u egyik >/tmp/egyik.tmp
sort -u masik >/tmp/masik.tmp
diff /tmp/egyik.tmp /tmp/masik.tmp
- A hozzászóláshoz be kell jelentkezni
Igy is lehet, bar igazabol akkor mar elotte cmp-vel osszehasonlitom, es ha van elteres, akkor megyek ra diffel. A cmp-nek ugyanis van "kuss" parametere, nem kell a kimenetet elnyomni.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
diff <(sort -u egyik) <(sort -u masik)
- A hozzászóláshoz be kell jelentkezni
"diff <(sort -u egyik) <(sort -u masik)" ez a parancs nekem a "másik" teljes tartalmát visszaadja
- A hozzászóláshoz be kell jelentkezni
Első felindulásra lehetetlennek gondolom, mert ennek valami diff-szerű kimenetnek kellene lennie. Nincs ott minden sor előtt pl. egy + vagy egy "kacsacsőr" jel?
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
de ott van a kacsacsőr :)
ennek örüljek vagy ne?:D
- A hozzászóláshoz be kell jelentkezni
Egyrészt örülj, mert nem romlott el a géped, és a diff parancs működik :)
Komolyra: nem lehet, hogy a másik fájl töküres? Akkor kellene az egyiket egy "kacsacsőrrel" megbolondítva visszaadni, ha a másik üres. Egyébként biztos, hogy a teljes tartalmat kapod vissza?
Ha esetleges publikus, tényleg feltolhatnád valahova az említett fájlokat.
- A hozzászóláshoz be kell jelentkezni
sajnos nem publikus, amúgy az első fájl 507 a második 725 sorból áll
a diff pedig 1234 soros kimenetet ad (tehát első fájl + második fájl + 2 sor)
annyi van még, hogy a 2. fájl postgres adatbázisból lett lekérdezve, és minden sor elé betett a szerencsétlen egy szünetet
ezt néhány sor esetén kitöröltem, hogy lássam hogy ez jelent-e bármit is, de egyelőre nem úgy tűnik mintha ez bármit is számítana
- A hozzászóláshoz be kell jelentkezni
Próbáld teszt file-okkal. Egzakt azonosság kell. Teszem azt, nem mindegy, hogy van szóköz elején, végén, ha van, akkor hány darab, nem jó az sem, ha az egyik file-ban tabulátor, a másikban szóköz van. Ha ilyen a probléma, akkor hozd a file-okat egységes formára előbb.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Hoppá... itt még azt írtad, hogy a második fájl teljes kimenetét kaptad, most meg az, hogy mindkettő + 2 sor (gondolom a +2 sor lesz az utolsó sor a fájlban, ami egy-egy szimpla üres sor).
Viszont ennek fényében a uniq -d-vel szűrt verzió esetében nem csoda, ha üres kimenetet kapsz, hiszen a sorok NEM egyformák! Először azt kell megtenni, hogy a sorok szerkezete mindkettő fájlban ugyanaz legyen! Amit már írtál: egy-egy szünet van a sorok előtt. Ha gondolod, állj neki kézzel, de inkább egy sed lehet rá gyógyír:
sed "s@^ *@@" beteg_fájl | sort -u
sorra kell módosítani az eredeti parancsot, amit mutattam.
Csak egy kérdés: jól sejtem, hogy neked azok a sorok kellenek, amelyek mindkettő fájlban szerepelnek?
- A hozzászóláshoz be kell jelentkezni
Lehet
sed -r 's/^ *//; s/ +/ /g; s/ *$//'
lenne, amit használnék, már feltéve, hogy szóközök csak szeparálásra vannak, viszont egyes helyeken hol kevesebb, mint másokon hol több. A végén a $ előtti * fölsleges is, mivel előtte egy szóközre cseréltük, ha volt.
Miért szeretted jobban a kukacot a pernél?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Azért használom inkább a kukacot, mert azt könnyebb "észrevenni", nekem valahogy jobban "szemreáll", mintha vesszővel vagy perrel vagy függőleges vonallal vagy akármivel lenne elválasztva:
sed -r 's/^ *//; s/ +/ /g; s/ *$//'
vs.
sed -r 's@^ *@@; s@ +@ @g; s@ *$@@'
Bazinagy karakter, kitölti a helyet, így nem olvad a többi karakter közé, "kilóg" a többi közül. Ja, és viszonylag ritkán használjuk, ritkán fordul elő, hogy a kukacra hajtunk, így lehet szeparátorként használni :)
- A hozzászóláshoz be kell jelentkezni
A tipikusan sztringcserére (azért makrónyelv) használt m4-gyel kezelt fájlokban szereplő makrókat ugyanezért terminálják jellemzően @-tel.
A bármicsaknemperjel használatának a shellben megvan az az előnye, hogy a shellben gyakran fájlneveket forgácsolunk, és ott nem jön rosszul, ha jól látszik, hogy mi hová tartozik, ha nem jobbra-balra dőlő kerítés a fél parancssor.
- A hozzászóláshoz be kell jelentkezni
Hát, pedig azt hittem, feltaláltam a melegvizet :)
- A hozzászóláshoz be kell jelentkezni
Ebben a bizniszben végképp érvényes a közhely, hogy hasonló problémára hasonló megoldások születnek.
Elárulom, hogy bennem is bőven azután tudatosodott, hogy ilyesmit láttam már valahol, miután már rutinná vált így használni, ha könyvtáras manipulációra kell.
Engem is meglep, hogy ugyanez szokás az awk konstans regexpjeinél, vagy perlben a q* operátoroknál véletlenül se jön elő az ujjaimból.
- A hozzászóláshoz be kell jelentkezni
En csak akkor hasznalok kukacot, ha tudom, hogy perjelre keresek vagy cserelek. Nekem a per is eleg kirivo jel egy, ezen kivul alapvetoen kisbetuket es szokozoket tartalmazo patternben.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Pontosan ilyen helyzet az elérési úttal prefixált fájlnevek kezelése.
- A hozzászóláshoz be kell jelentkezni
Stimm, elboktem amugy a valasz gomb megnyomast, igazabol uzsoltra reagaltam.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
nem, nekem azok a sorok kellenének, amelyek csak az egyik fájlban szerepelnek
a legkirályabb megoldás az lenne ha csak azokat a sorokat kapnám meg, amelyek az első fájlban benne vannak de a másodikban nem
konkrétan az a gondom, hogy AD-ben vannak hosztok, és a Zabbix adatbázisában is vannak hosztok
viszont az AD lista egy naprakész lista, ami abban benne van az kellene hogy benne legyen a Zabbix adatbázisában is
Sajnos a zabbix autodiscovery funkciója eléggé ratyi...
API-val lehetne a zabbix adatbázisába új hosztokat felvenni,
de mivel általában nincs túl sok új hoszt, ezért simán meg tudom csinálni a hosztok felvételét kézzel is
na és ehhez kellene egy script, ami visszaadja azokat a hosztokat, amelyek a zabbix adatbázisában (ill. egy ebből lekérdezett listában) nincsenek benne,
de az AD-ből lekérdezett listában benne vannak.
- A hozzászóláshoz be kell jelentkezni
Akkor szerintem lx megoldása lesz jó, csak előtte egy kicsit formázni kellene a fájlokat, valami ilyesmi:
join -v 2 <(sort -u egyik | sed akármi) <(sort -u masik | sed akarmi)
- A hozzászóláshoz be kell jelentkezni
Elszörnyedtem. :) Egyrészt hiányoznak idézőjelek, ami nem olyan jó, ha valahol szóköz van esetleg. Aztán minek a cat, amikor a grep és a head is tud file-t olvasni. Ami a legfontosabb, az viszont az, hogy a grep argumentuma regexp, így például egy pont karakter bármire illeszkedik. Nagyon nem így csinálnám, de ha már így teszed, akkor grep -F, vagy valami ilyesmi.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Donna Clara... Mi a feladat? nekem awk jut az eszembe...
(sort -u lista1.lst | sed 's/^/1\ /'; sort -u lista2.lst | sed 's/^/2\ /' ) |
awk -v MIT=3 ' { sum[$2]+=$1; }
END { for (host in sum) {
if ( sum[host] == MIT ) {
print host;
}
}
}'
Ha MIT=1, akkor csak azokat listázza, amik csak az elsőben, ha MIT=2, akkor azokat,a mik csak a másodikban, ha MIT=3, akkor azokat, amik mindkettő listában szerepelnek.
Ha csak azokra van szükség, amik mindkettőben szerepelnek, akkor egyszerűbb:
(sort -u lista1.lst | sed 's/^/1\ /'; sort -u lista2.lst | sed 's/^/2\ /' ) |
awk '{ sum[$2]+=$1;
if ( sum[host] == 3 ) {
print host;
}
}'
De lehet pl. azt is csinálni, hogy a rövidebb listából csinálsz egy mintafájlt (e)grepnek:
sed ' sed 's/^/\^/
s/$/\$/
s/\./\\\./g' < lista1.lst > egrepfile
aztán egrep -f egrepfile lista2.lst adja meg ami mindkettőben szerepel.
- A hozzászóláshoz be kell jelentkezni
Amikor a file sorszámát beszúrod a sorok elé, a sed-ben minek a szóköz elé a backslash?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Az nem jó megoldás, hogy mindkét fájlt abc sorba (sort) rendezed, majd a diff paranccsal összehasonlítod?
Bocs, későn vettem észre: http://hup.hu/node/125085#comment-1614650
- A hozzászóláshoz be kell jelentkezni
Ha már rendezettek a fájlok, akkor a diff parancsnál fogyaszthatóbb kimenetet ad a méltatlanul elfeledett join parancs -v paraméterrel hívva.
$ cat a
1.ez.lesz
2.ez.is.lesz
3.es.meg.ez.is
$ cat b
1.ez.lesz
1.ez.viszont.nem.lesz
2.ez.is.lesz
2.ez.se.lesz
3.es.meg.ez.is
3.es.meg.ez.se.lesz
$ join -v 2 a b
1.ez.viszont.nem.lesz
2.ez.se.lesz
3.es.meg.ez.se.lesz
- A hozzászóláshoz be kell jelentkezni
kipróbáltam a "join -v 2 egyik.txt masik.txt" parancsot, és az "egyik" fájl teljes tartalmát megkaptam a kimeneten
- A hozzászóláshoz be kell jelentkezni
Kellene látni azt a két file-t!
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Eredeti kerdezo: a sorvegjeleket kene megnezni a ket bemeneti faljban, kulonbozhetnek. Vagy a karakter kodolast.
- A hozzászóláshoz be kell jelentkezni
fordítva próbáld és rendezve (fontos, hogy a két fájlban nem lehet semmilyen eltérés az adatokon kívül... azaz szóköznek valamint a soremelés formátumnak azonosnak kell lennie (unix<->unix vagy dos<->dos, úgy tudom az is gond, ha dos<->unix esetleg még 3.-ra bejön a machintos is...):
Üres sorok nem okoztak nálam gondot ment rendesen...
Szépen kilistázta azt ami az ad-ban benne volt, de a zbx-ben nem:
join -v 2 <(cat /tmp/zbx_hosts|sort -u) <(cat /tmp/ad_hosts|sort -u)
DDD.EEE.GGG
valamint, ami a zbx-ben benne volt, de ad-ban nem:
join -v 2 <(cat /tmp/ad_hosts|sort -u) <(cat /tmp/zbx_hosts|sort -u)
FF.DD.ASD
#cat /tmp/ad_hosts
AAA.BBB.CCC
AAA.BB.CC
AAB.AAD.CF
BBB.DD.AED
DDD.EEE.GGG
#cat /tmp/zbx_hosts
AAA.BBB.CCC
AAA.BB.CC
AAB.AAD.CF
BBB.DD.AED
FF.DD.ASD
Üdv:
Csabka
- A hozzászóláshoz be kell jelentkezni
A sort-nak is lehet file paramétere, nem kell a cat.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
tudom, csak megszokás :-)... igazság szerint azért szoktam így, hogy ne kelljen visszamenni az elejére :-) cat /h/o/s/s/zu/path/es_hosszu_fájl_nev | {grep|sort|uniq -d|awk|sed} így menet közben csak a végét kell visszatörölni ha épp meggondolom magam melyik parancs követi a pipe-ot
shell scripten belül általában nem szoktam cat-olni, hanem sort vagy grep egyből olvas fájlt is...
lustaság na :-D
- A hozzászóláshoz be kell jelentkezni
Egyébként az ilyet érdemes egy uniq-kal bolondítani. Ha csak az kell, hogy melyek azok, amelyek mindkét fájlban benne vannak:
sort egyik masik | uniq -d
és kész is.
- A hozzászóláshoz be kell jelentkezni
Ez azokat a sorokat is kiírja, amik többször vannak az egyik file-ban, de nem szerepelnek a másikban.
- A hozzászóláshoz be kell jelentkezni
Hopp, valóban. Akkor:
sort <(sort -u egyik) <(sort -u masik) | uniq -d
- A hozzászóláshoz be kell jelentkezni
+1
Az eddigi legszebb megoldás szerintem.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Azért lx megoldása sem piskóta :)
- A hozzászóláshoz be kell jelentkezni
Való igaz, de nem is ugyanazt csináltátok. A Te megoldásod minden különbséget kiír, az övé viszont csak azt, amikor az egyik file-ban nincs meg az, ami a másikban megvan. Azt nem írja ki, amikor a másik file-ban nincs meg az, amelyik az egyikben megvan.
Az eredeti feladathoz szerintem az ő megoldása illeszkedik inkább. Ugyanakkor lx nem írta le az elejét, azaz a rendezést például process helyettesítéssel, ahogy tőled láthattuk.
A fentieket azért írtam, mert ha keressük, mi az, ami nincs a file-ban adott lista alapján, akkor aligha kérdés, hogy mi az, ami meg nincs a listánkban, s a file-ban van.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Csak az eredeti feladatot nem tudjuk, csupán egy rosszul működő kódot osztott meg spider. Ebből próbáltam meg kitalálni, hogy mi lehetett az eredeti "feladat", amire a kód íródott.
Mivel már nekem is kellett néhányszor ilyen, ezért (lehet, hogy tévesen) arra gondoltam, hogy azok a sorok kellenek neki, amelyek mindkét fájlban megvannak.
- A hozzászóláshoz be kell jelentkezni
Ja igen, bocs, rosszul írtam. A tied valóban a mindkét file-ban meglévőket listázza, míg az inverzét írtam tévesen.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Kipróbáltam, de teljesen üres kimenetet kapok... :/
- A hozzászóláshoz be kell jelentkezni
Milyen shellel?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Hopp, valami gikszer van akkor.
A fájlok milyenek? Tehát mindkettő ugyanolyan "formátumú", tehát egyiknél sincs a sor végén extra szóköz és hasonlóak...
- A hozzászóláshoz be kell jelentkezni
Várd ki a végét, process helyettesítést nem tudja mindegyik shell.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Akkor meg valami hibaüzenetnek lennie kellene, nem pedig ürességnek. Eszerint meg valami csak történik.
- A hozzászóláshoz be kell jelentkezni
Ezek szerint valóban az adatfile-okkal lesz a baj.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Bedobom még a comm parancsot is. :-)
KisKresz
- A hozzászóláshoz be kell jelentkezni
Ha egy host egy fájlban csak egyszer van, akkor így csinálnám:
cat elso.txt masodik.txt masodik.txt|sort|uniq -c| awk '
$1==1 {print "Csak az elsoben: "$2}
$1==2 {print "Csak a masodikban: "$2}
$1==3 {print "Mindkettoben: "$2} '
Ha esetleg többször is előfordulhat, akkor kicsit bonyolítjuk:
{ sort elso.txt|uniq; sort masodik.txt|uniq; sort masodik.txt|uniq; }|uniq -c| awk '
$1==1 {print "Csak az elsoben: "$2}
$1==2 {print "Csak a masodikban: "$2}
$1==3 {print "Mindkettoben: "$2} '
- A hozzászóláshoz be kell jelentkezni
A sort | uniq
helyettesíthető sort -u
paranccsal.
A cat elso.txt masodik.txt | sort | uniq
pedig egyszerűen egy sort -u elso.txt masodik.txt
.
- A hozzászóláshoz be kell jelentkezni
A cat elso.txt masodik.txt | sort | uniq pedig egyszerűen egy sort -u elso.txt masodik.txt.
Nem igazán. Azzal trükközik, hogy a uniq -c-vel beszúr egy számot a sor elejére. Ez a szám azt mondja, hanyadik file-ból van a sor, de összeadódik - 3 -, ha mindkettőben. Az awk-val ezt szűri. Tehát csak picit lehet egyszerűsíteni:
sort elso.txt masodik.txt masodik.txt | uniq -c
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
De. Ui. nem mindenhol használja a -c
opciót. Ahol használja, azt békén hagytam :)
Viszont valóban pont rossz példát ragadtam ki, ott épp volt -c
.
- A hozzászóláshoz be kell jelentkezni
Nem is ott javítottalak, ahol jól írtad. ;)
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Jaja :)
Viszont a -c nem egészen azt csinálja, amit írtál, ui. a -c az előfordulások számát adja meg, nem a helyét.
Szerk.: oké, értem, mire gondoltok.
- A hozzászóláshoz be kell jelentkezni
Igen, a számát adja meg. A cat-nek - egyszerűsítés után a sort-nak - 3 argumentuma van: egyszer az első file, s kétszer a második. Ezért ami a második file-ban van, az számszerint 2-t fog kapni - ha az elsőben is van ilyen sor, akkor 3-at -, ami csak az első file-ban van, az 1-est kap. Így aztán végül mégis csak azt mutatja meg a szám, melyik file-ból jön a sor.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
néhány dolgot biztos másképp csinálnék... pl szerintem szebb, ha seq helyett:
for ((i=1 ; i <= $AD_list_size; i++)); do..
a másik, hogy jó lenne pontosan tudni az input adatok kinézetét még ha nem is az eredeti adatokkal
pl:
" AA.HOST1.BB "
" AC.HOST1.CC"
" AD.HOST2.DD "
" AF.HOST2.FF"
" EFG.AF.HOST2.FF"
" _AAA_.BBB.CCC"
stb... lehessen látni, hogy is van...
Logikádat követve, tömbbe tenném (persze a többiek sok szebb megoldást postoltak, ami gyorsabb... de legyen ez is itt :-) )
a biztosan nincs se szóköz se extra karakter csak és kizárólag a host nevek egymás alatt, se fejléc se lábléc akkor én tömbbe tölteném:
---------------
#!/bin/bash
AD_hosts=/tmp/ad_hosts
zbx_hosts=/tmp/zbx_hosts
TOMB=($(cat $AD_hosts | sort -u))
AD_list_size=${#TOMB[@]} #ennyi db elem van a tombben
# tegyuk bele egy valtozoba a teljes ZBX listat is, de itt is
# figyeljunk, hogy csak a hostok legyenek se komment semmi egymas alatt
# es a sor elejen kezdodjenek es a vegen ne legyen szokoz
# de ezt ne tombbe, mert ugy bonyolultabb lenne
ZBXLIST="$(cat $zbx_hosts | sort -u )"
for ((i=0;i < "${#TOMB[@]}";i++)); do
echo "sorszam:|$i| tartalom:|${TOMB[$i]}| masik:|$(echo "$ZBXLIST"|egrep "^${TOMB[$i]}$")|"
if echo "$ZBXLIST" | egrep -q "^${TOMB[$i]}$"; then
#kivenni a listabol, hisz van ilyen, ne kelljen atnezni az egesz listat ujra:
ZBXLIST=$(echo "$ZBXLIST" | egrep -v "^${TOMB[$i]}$")
else
echo " -> hianyzik a ZABBIX-bol: ${TOMB[$i]}"
fi
done
-----------------
/tmp/aaa.sh
sorszam:|0| tartalom:|AAA.BBB.CCC| masik:|AAA.BBB.CCC|
sorszam:|1| tartalom:|AAA.BB.CC| masik:|AAA.BB.CC|
sorszam:|2| tartalom:|AAB.AAD.CF| masik:|AAB.AAD.CF|
sorszam:|3| tartalom:|BBB.DD.AED| masik:|BBB.DD.AED|
sorszam:|4| tartalom:|DDD.EEE.GGG| masik:||
-> hianyzik a ZABBIX-bol: DDD.EEE.GGG
- A hozzászóláshoz be kell jelentkezni
De ennél szebb nincs:
for i in {0..${AD_list_size}}; do...
- A hozzászóláshoz be kell jelentkezni
A while read line -ban mi a nem szep szerinted? Kodot lasd kisse fentebb.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant.
- A hozzászóláshoz be kell jelentkezni
Csak a sima for-ciklus megvalósítására írtam (márhogy a seq nem jó), a kapcsos zárójeles megoldást "szebbnek" tartom.
Fájlolvasásra inkább más módszert (pl. az általad is írt while-read-line-szerűséget) használnék.
- A hozzászóláshoz be kell jelentkezni
Ha jól tévedek, ez ugyanúgy telenyomja a teret a célértékig tartó számsztringekkel, mint a seq. Nyilván ez itt nem lehet tétel, de jó tudni róla, mielőtt az ember 10^8 nagyságrendű logrekordnál is beveti.
- A hozzászóláshoz be kell jelentkezni
Jól tévedsz :)
Viszont bash-ban is van "maxint", tehát egy időn túl a c-szerű for-ciklus sem használható erre.
- A hozzászóláshoz be kell jelentkezni
Ha jól emlékszem, 64 bites az ábrázolás, szóval a memória jóval hamarabb szalad tele.
off
Bash-ből a float ábrázolást hiányolom, elég kellemetlen, hogy bc-vel, dc-vel, calc-kal, awk-val kell bohóckodni, ha lebegőpontos számításra van szükség.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
$ float x=2.3
$ (( y=2*x ))
$ echo $y
4.600000000e+00
Bár ez zsh :)
- A hozzászóláshoz be kell jelentkezni
Grrr... Mondom bash. :)
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Én pedig írtam, hogy ez zsh :) Hogy egy kicsit irigykedj ;)
/csak jó ez a zsh, eddig, ami bash-ben ment, ment itt is, ugyanolyan eredménnyel, meg az is, ami bash-ben nem megy, itt megy :) /
- A hozzászóláshoz be kell jelentkezni
És van rengeteg dolog, ami bash/csh/ksh/zsh alatt műx, sőt, hála a "fejlődésnek" sokszor ugyanaz a program más-más verzióban, azonos kapcsolókkal egészen más kimenetet produkál. Legutóbb pl. az "ls --full-time" örvendeztetett meg ilyesmivel, igaz, némileg múzeumi darab volt a régebbi verzió, de akkor is...
- A hozzászóláshoz be kell jelentkezni
Tehát érdemes lenne elcsábulnom zsh-ra? Jó volna látni valami összehasonlító doksit, amiből kiderül, mi az, ami másként van a különféle shellekben.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
:)
5 perce a mant, ill manokat olvasom (több van neki, mivel összetettségében messze több, mint az ismert shellek; ahogy elnézem, a perlt már jobban közelíti, mint a *sh-t).
Akad pár megírt és megírandó nagios szkript, ahol a perl még overhead, és pár ponton gát, a *sh meg még sutácska, nem zárom ki, hogy elkezdem megszokni ezt is. Mostanában úgyse tudom, hogy azért lesz a füles, mert van rajtam vaskalap, vagy azért, mert nincs.
- A hozzászóláshoz be kell jelentkezni
Én már átcsábultam rá. Hétköznapi használatban különösebben nagy különbséget nem fogsz tapasztalni, csak több lehetőséget. Pl. az ls -
után tab-ot nyomva a lehetséges paramétereket írja ki, rövidke kis help-et mellé. Ha egy "*" után nyomsz Tab-ot, kifejti "röptében", stb.
Nem nagyon kell megszokni, ha a bash ment, akkor a zsh is menni fog. Itt-ott van némi különbség, de szerintem szeretni fogod.
Meg volt egy idegesítő hiba bash-ban, valahogy bizonyos körülmények között, ha hosszú parancssort írtam be, akkor néha nem a következő sorban folytatódott, hanem abban a sorban, amiben írtam (mintha nem lett volna sortörés). Néha meg jó volt :)
- A hozzászóláshoz be kell jelentkezni
A parancssori paraméterek listáját/kiegészítését tudja a bash is.
Pontosabban annyit tud belőle, amennyit az adott parancshoz "pluginként" hozzáadtak - valószínűleg ez a zsh-nál is így van.
Lásd a man Programmable Completion részét.
- A hozzászóláshoz be kell jelentkezni
És ilyet is tud a bash? Hogy nem csak a listát adja meg, hanem mellé pár szavas súgót?
Persze, ezt le kellett programozni, de tudomásom szerint bash csak listát tud adni, mellé nem tud súgót is.
- A hozzászóláshoz be kell jelentkezni
(Ezt inkább töröltem, mert nem a kérdésre válaszolt. Érdemi válasz később.)
- A hozzászóláshoz be kell jelentkezni
Tévedtem, mégis a kérdésre válaszolt.
Ha jól látom, nincs itt help, csak a nem egyértelműsíthető elem miatt a lehetőségek teljes listájának megjelenítése, mint általában a kiegészítéseknél. Pont ezt teszi a bash is.
De tud ez ennél többet is, csak én hanyagoltam el a témát, amióta fel akartam magamnak paraméterezni a DB2-höz.
- A hozzászóláshoz be kell jelentkezni
Nem-nem. Pl. egy sor:
--recursive -R -- list subdirectories recursively
Hosszú opció, rövid opció, néhány szó, hogy az adott opció mit csinál. Bash esetében pedig "csak" kiírja az összes lehetséges opciót.
- A hozzászóláshoz be kell jelentkezni
Ilyet biztosan nem tud, pedig szerintem igény, az lenne rá :-P
# pwd
/tmp/a/aa/ac/ad
# cd aa ab
/tmp/a/ab/ac/ad
# pwd
/tmp/a/ab/ac/ad
#
- A hozzászóláshoz be kell jelentkezni
A CDPATH hasonlóra van kitalálva - de persze azt megint csak be kell előbb állítani.
- A hozzászóláshoz be kell jelentkezni
Márhogy az "aa" könyvtár helyett az "ab" könyvtárban (és annak megfelelő alkönyvtárában) legyen?
Szerk.: ja, hogy a zsh ezt tudja... na, ezt nem tudtam, ez tényleg nem hülyeség, ha patch-et gyárt az ember :)
- A hozzászóláshoz be kell jelentkezni
Mégsem egészen jó a tévedésem, ui. bash-ben egyáltalán nem szalad meg. Mivel ott a sorozatkifejezés határai csak literálok lehetnek, kifejezések nem, egyszerűen nem lesz in-lista, ill. csak ami betű szerint a parancsban szerepel.
Ha nem említed lentebb, hogy zsh, be sem ugrik.
- A hozzászóláshoz be kell jelentkezni
Tehát a brace expansion röptében kerül kifejtésre, s nem állítja elő a listát, amit aztán felhasznál abban a környezetben, ahova írták? Mert ez nagyon nem mindegy!
Azaz mondjuk az
echo {a..f}{0..9}
röptében generálja az elemeket, s írja ki az echo, vagy a két egymásba ágyazott ciklus előállítja a teljes listát, s ezt kapja meg az echo?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Emlékeim szerint itt közönséges permutációról van szó, aztán végrehajtásról (azért expansion).
Nem erre céloztam fentebb, hanem arra, hogy a zsh megérti, hogy a
X=3
for i in {0..${X}} ; do echo $i; done
paranccsal a 0,1,2,3 listát akarod generálni és bejárni, míg a bash esetén csak akkor generál listát (4.1.5-ben legalábbis), ha a ${X} helyett literálisan 3-at írsz. Máskülönben szó szerint az lesz a listád, és ezáltal a kimeneted, hogy
{0..3}
Nincs 2. feloldás.
- A hozzászóláshoz be kell jelentkezni
Kicsit béna, de így lehet azért:
x=3; for i in `eval echo {0..${x}}`; do echo $i; done
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Persze, az eval mindent visz; általában az első az olvashatóság, amit el szokott vinni. :)
- A hozzászóláshoz be kell jelentkezni
4.2.45-ben sincs kettős feloldás. Zsh-ban viszont van, ez is egy plusz a zsh mellett :)
- A hozzászóláshoz be kell jelentkezni
> nekem azok a sorok kellenének, amelyek csak az egyik fájlban szerepelnek
> a legkirályabb megoldás az lenne ha csak azokat a sorokat kapnám meg, amelyek az első fájlban benne vannak de a másodikban nem
> konkrétan az a gondom, hogy AD-ben vannak hosztok, és a Zabbix adatbázisában is vannak hosztok
> viszont az AD lista egy naprakész lista, ami abban benne van az kellene hogy benne legyen a Zabbix adatbázisában is
Feltételezhetjük, hogy mind az ad_list.txt-ben mind a zabix_list.txt-ben egy hostnév csak egyszer szerepel, de azt nem hogy ezek sorrendben is vannak.
Első lépésként tehát ezeket a fájlokat sorrendbe rakjuk (ha esetleg szerepelhet akármelyikben egy hostnév duplán akkor a -u kapcsoló is kell)
sort -o ad_list.txt ad_list.txt
sort -o zabbix_list.txt zabbix_list.txt
Majd a sorbarendezett fájlokkal már működni fog ez:
sort -m ad_list.txt zabbix_list.txt | uniq -u | sort -m - ad_list.txt | uniq -d
Itt az elso "sort" összefűzi a sorrend megtartásával a két állományt.
Az utánna következő "uniq", legyüjti azokat a sorokat amik csak valamelyik állományban találhatóak meg.
A következő "sort" újra összefűzi a megkapott listát az AD listával, így azzok a sorok amik az AD listában találhatóak meg, most duplán fognak szerepelni.
Az utolsó "uniq" pedig kiszűri a szimplán előforduló hostneveket. Így pont azt kapod ami neked kell.
- A hozzászóláshoz be kell jelentkezni
Nagyon tetszik az ötlet, köszönet érte! Eddig a sort-ot csak simán rendezésre használtam, a uniq-ot pedig csak a duplikátumok eldobására. Sohasem néztem meg a többi kapcsolót, s nem tünődtem el azok használhatóságán. Ebben a topic-ban sok jó ötlet látott napvilágot.
Az elején a sort -o file file biztos, hogy jó úgy? Szerintem az input file-t írásra megnyitni nem jó ötlet, mert 0 hosszúságú lesz, így rövid file-nál, ha már a tartalmát berántotta RAM-ba, akár még működhet is, de hosszú file-nál szerintem elromlik. Szerintem a sort -o file1 file2 lenne jó, tehát a kimeneti file ne legyen azonos a bemenetivel.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Nem sűrün használom így, hogy saját magába íratom vissza a végeredményt, de amikor igen, akkor még sosem volt ez gond. Lehet csak szerencsés vagyok, de biztosat csak a "sort" forrásának átnézése után lehetne mondani, mert lehet ez le van benne kezelve rendesen.
- A hozzászóláshoz be kell jelentkezni
Nem szép, de csúnya, és tényleg veszélyes játék, soha, semmi nem garantálja, hogy egy frissített sort verzióval is szerencséd lesz.
- A hozzászóláshoz be kell jelentkezni
Igaz, de belegondolva, a sort működéséhez elengedhetetlen hogy a kimenetre csak azután kezdjen adatot tolni, ha már minden bemenetet feldolgozott. Ha csak annyit tudna összehasonlítani ami belefér a memóriába az gáz lenne. Ha a fájl nem fér bele, akkor kisebb darabokban kell megcsinálnia, de kiírni nem kezdheti az első darab után sem, mert a későbbi darabokkal is össze kell hoznia a sorrendet.
Szóval elöbb mindenképp kellhet neki jópár átmeneti terület is, majd ugyanúgy ahogy az összefűzés része működik, ezeket a rendezett blokkokat is összefűzi. A több kisebb blokkot rendezni és késöbb összefűzni még jóval gyorsabb, hatékonyabb is lehet. (Biztos megvan mi az optimális elem szám amin még érdemes a rendezést elvégezni.)
- A hozzászóláshoz be kell jelentkezni
Ettől még megnyithatja a kimeneti fájlt írásra, létező fájl esetén 0 méretre csonkolva...
- A hozzászóláshoz be kell jelentkezni
sub...
- A hozzászóláshoz be kell jelentkezni
közben az eredeti probléma megoldódott :)
az egyik fájlom tele volt sor vége jelekkel, a másik viszont nem tartalmazott ilyen jeleket
ezért nem tudtam összehasonlítani őket se diff-el se grep-el se uniq-al
köszi mindenkinek a válaszokat! :)
- A hozzászóláshoz be kell jelentkezni