Üdv mindenkinek!
Már egy ideje szenvedek a tárgybelivel OpenWrt alatt.
Textfile.txt fájlban szeretném kicserélni "szoveg"-et $VALTOZO értékére. Pl.:
VALTOZO="TEXT"
export VALTOZO
sed 's/szoveg/${VALTOZO}/' textfile.txt >newtextfile.txt
De newtextfile.txt-ben a "szoveg" helyére "$VALTOZO" szöveg kerül,
nem a változó értéke. :(
Megoldás erre valkitől?
- 7394 megtekintés
Hozzászólások
sed "s/szoveg/${VALTOZO}/" textfile.txt >newtextfile.txt
de el is hagyhatod...
- A hozzászóláshoz be kell jelentkezni
Köszi. Az aposztróf és a macskaköröm néha megsz..at :)
- A hozzászóláshoz be kell jelentkezni
El véletlenül se hagyd. Azt *csak* abban az esetben szabad, ha tudod, hogy a fent TEXT-nek nevezett rész nem tartalmaz semmilyen, a shell számára jelentéssel bíró karaktert. Szóval idézőjel.
- A hozzászóláshoz be kell jelentkezni
Valóban, köszönöm a kiigazítást, egyébként én mostanában akkor teszem ki ha nem tudom mit fogok pontosan helyettesíteni, pont az általad említett "apróság" miatt :-)
- A hozzászóláshoz be kell jelentkezni
valamint /-t sem tartalmaz...
- A hozzászóláshoz be kell jelentkezni
A / a shell-nek nem faj, azaz ott az idezojel nem oszt, nem szoroz - a / a sed-nek fog problemat okozni.
- A hozzászóláshoz be kell jelentkezni
szerintem mindegy, hogy miért nem műx...
ez a fajta behelyettesítgetés akkor használható, ha a string értékkészlete korlátozott.
ha random szemét is lehet benne, és azzal is kéne mennie, akkor ezt így, shellből, orbitális szívás megcsinálni.
- A hozzászóláshoz be kell jelentkezni
az tény, hogy mindegy, miért nem működik, ellenben ha van / a sztringben, akkor idézőjellel és nélküle se működik, valamint aposztrófban sem. Én erre hívtam fel a figyelmet. És aki nem (vagy nem nagyon) ért hozzá, azt könnyen félrevezetheti az, amit írtál. (nagyon rossz hasonlat: 95-ös benzint tankoltam a dieselmotoros autómba. Az nem jó, használj 98-ast!)
- A hozzászóláshoz be kell jelentkezni
szerintem leírtad, hogy csak akkor szabad használni, ha nincs benne shell által értelmezett karakter. én hozzátettem, hogy akkor se fog működni, ha / van benne.
- A hozzászóláshoz be kell jelentkezni
VALTOZO="TEXT"
sed "s/szoveg/$VALTOZO/g" textfile.txt>newtextfile.txt
- A hozzászóláshoz be kell jelentkezni
jaja, a /g a végére kell, különben a sorban csak az első előfordulást cseréli ki a sed!
- A hozzászóláshoz be kell jelentkezni
VALTOZO="TEXT"
export VALTOZO
sed 's/szoveg/'"${VALTOZO}"'/' textfile.txt >newtextfile.txt
- A hozzászóláshoz be kell jelentkezni
Az export nem csak akkor kell, ha a szkripten kívül, annak lefutása után is használni akarod a változót?
--
Tertilla; Tisztelem a botladozó embert és nem rokonszenvezem a tökéletessel! Hagyd már abba és kész!
- A hozzászóláshoz be kell jelentkezni
így volt az eredetileg.
megtartottam:)
- A hozzászóláshoz be kell jelentkezni
Nem, az lehetetlen. Az export akkor kell, ha a scriptből indított programnak akarjuk továbbadni a változót. Esetünkben nincs szükség az export-ra.
- A hozzászóláshoz be kell jelentkezni
Threadnekromanta!!!!!!
--------------
„If there were no hell, we would be like the animals. No hell, no dignity.”
- A hozzászóláshoz be kell jelentkezni
Hoppá, ezt benéztem, bocs' és pardon;)
- A hozzászóláshoz be kell jelentkezni
Sziasztok!
Kis segítséget kérnék, megakadtam...Gondolom nem látom a fától az erdőt, de nem jön össze.
Van két fájlom. uj.txt regi.txt
Az uj.txt fájlban lévő több ezer sor közül ki szeretném törölni, amit már tartalmaz a regi.txt
A fájlok így néznek ki
valamilyen név|12345|valamilyen szöveg
Ezzel próbálkozom, de nem megy
#!/bin/sh
for i in $(cat regi.txt); do
for j in $(echo $i | cut -d"|" -f2); do
sed -i "/$j/d" uj.txt
done
done
Mit nézek be?
Ha ki echo-zom, akkor szépen kiírja a számokat (második oszlop). Ha a sednek a $j helyett megadok egy számot simán törli a sort, ahogy kellene, de így nem működik. Az összes sort meghagyja.
Próbáltam így is:
#!/bin/sh
for i in $(cat regi.txt); do
for j in $(echo $i | cut -d"|" -f2); do
sed -e "/$j/d" uj.txt > test.txt
done
done
Ekkor az összes sort beleírta a test.txt fájlba...
Előre is köszönöm!
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
A fájlokban van jelentősége a sorrendnek?
Ha igen: egyforma sorrenben vannak a két fájl sorai?
Mert ha egyforma sorrendben szerepelnek vagy nincs jelentősége a sorrendnek, akkor előbbi esetben rendezés nélkül, utóbbiban előbb rendezném mindkettőt és egy diff-fel válogatnám ki a felesleges sorokat.
(tévedés jogát fenntartva: diff -u kapcsoló + némi grep talán)
Aki 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
Tényleg, a diff talán alkalmasabb erre.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Volt valami hasonló topik egyébként, ahol a sort, uniq, diff, join, cut, cat halmazon születtek ötletesebbnél ötletesebb megoldások, úgy emlékszem.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Köszönöm, ennek mindjárt utána is nézek...
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
Ebben a topikban sok jó ötletet találsz. :)
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Nekem is rögtön ez ugrott be :)
- A hozzászóláshoz be kell jelentkezni
A fájlokban azonosak az oszlopok (szöveg, szám, szöveg) csak a tartalmuk térhet el. A más szöveg oszlophoz más számsor tartozik, ezért is a számokra szűrtem, mert abban nincs szóköz, zárójel, perjel, stb. amit a sed nem szeret... üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
Szerintem rendezd sorba a file-okat, majd használd a join parancsot talán a -v opcióval. Most nincs kedvem gondolkodni rajta, de szerintem errefelé elindulva jóval kisebb futásidővel meg tudod oldani.
Egyébként miért nem új topikot nyitottál? Ezen már ott van, hogy megoldva, nem feltétlenül foglalkoznak vele.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Ez akár műkodhet:
awk -F\| \
-v regi=regi.txt \
'BEGIN {
OFS=FS
while ( getline < regi )
kulcs[( "A" $2 )]+=0
close(regi)
}
{
if ( ( "A" $2 ) in kulcs )
next
print $0
}' uj.txt >test.tx
- A hozzászóláshoz be kell jelentkezni
Mivel ebben az egyszerű kódban látszólag sem logikai sem szintaktikai hibát nem lehet látni és azt mondod nem működik, kipróbáltam. Arra az eredményre jutottam, hogy ez bizony úgy dolgozik ahogy elvárod/elvárnád tőle.
A hiba nem a scriptben van!
--------------
„If there were no hell, we would be like the animals. No hell, no dignity.”
- A hozzászóláshoz be kell jelentkezni
Ezen nyűglődöm én is. Ha a $j helyett berakom az egyik számot és nem a script-en belül futtatom, akkor működik.
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
Mind a ketten azt nezitek be, hogy a kulso for ciklus nem jol fog lefutni. Ez: for i in $(cat regi.txt)
Ugyanis itt a 'valamilyen nev|szam|valamilyen szoveg' nem egy sorkent egyben, hanem sok parameterkent fog szerepelni. Ha pl. pont ez van benne, akkor egyszer lesz az hogy "valamilyen". A mogotte allo szokoz miatt a kovetkezo erteke a ciklusvaltozonak az lesz, hogy "nev|szam|valamilyen". Majd a harmadik ciklusban "szoveg" lesz a ciklusvaltozo erteke.
- A hozzászóláshoz be kell jelentkezni
+1
Ezért szoktam while read; do ciklusmag; done
szerkezetet használni.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
+1 Én is így szoktam...
--------------
„If there were no hell, we would be like the animals. No hell, no dignity.”
- A hozzászóláshoz be kell jelentkezni
Hmmm, csakugyan...
--------------
„If there were no hell, we would be like the animals. No hell, no dignity.”
- A hozzászóláshoz be kell jelentkezni
Nem igazán értem, mit szeretnél. Az i változóban a regi.txt egyetlen sora van. Még abban sem vagyok biztos, hogy nem esik szét szóközök mentén, de ezt most hagyjuk.
Az egyetlen sor (i változó) második mezeje | szeparátorral az 12345 lesz. A j ezen elemeken megy végig, de mindösszesen egy elemű a felsorolásod szerintem. Tehát a belső ciklus egyetlen egyszer fut le, mégpedig j=12345 értékkel. Lehet, hogy nem így van, de valahogy most nagyon ez az érzésem.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
A dolog egyszerű:
- a for ciklus változólistája idézőjelek nélkül a szeparátort tartalmazó soroknál szétszakad (SPACE) Pl. a "Kovacs Geza|12345|bolond" esetén a for 2db változót kap. Az egyik a Kovacs...
Az ilyen dolgok idézőjelek alkalmazásával passzolhatók, de bonyolult.
- a sed -i tmp állománnyal dolgozik = Sebesség szempontjából ixj esetben olvassa, írja és tmp állományba írja a feldolgozást. Optimális! - És csak gnu sed esetén megy.
A hiba vélhetően a fenti jelenség miatt keletkezik.
- a sed -e pedig ixj esetben kiírja a teljes eredményt, de csak 1db j esetére. Azaz ixjx kiírja...
A sorrendfüggetlen, mezőszeparátorokat pontosan kezelő megoldás az, amit korábban írtam.
Sebesség szempontjából:
- két állomány olvasás
- egy állomány írás + egy mv
- sebesség elég jó: bemenő adat 7.000.000db, kulcs 22.000db, mezőszám 40
futásidőt nem írok, mert megzavarna...
- A hozzászóláshoz be kell jelentkezni
Fentebb azt, hogy miert nem megy, mar leirtam. Speciel nem csak a SPACE, hanem minden szeparator ami az IFS shell-valtozoban van darabokra tordeli az adatokat (IFS alapbol szokoz, tabulator, soremeles).
Mindazonaltal jo lenne vegre tudni, mi a feladat. Ugyanis az eredeti kiiras szerint azokat a sorokat akarja torolni az egyik fajlbol, amik a masikban megvannak. Azaz teljes sor egyezese eseten akar torolni. Ebben az esetben pedig pl. a sor belso felepitese rohadtul nem erdekes. A legtobb megvalositas - a tied is - csak a masodik mezo egyezeset nezi, nem pedig a teljes sor egyezeset. Az awk-s megoldas egyebkent kifejezetten tetszik, eltekintve attol, hogy szerintem nem jo dolgot vizsgal.
- A hozzászóláshoz be kell jelentkezni
Kicsit roviditenem, es ahogy szerintem mukodnie kene - azzal egyutt is, hogy az otlet bucko-e:
awk -v regi=regi.txt '
BEGIN {
while ( getline < regi )
kulcs[ $0 ] += 0
close(regi)
}
! ( $0 in kulcs )
' uj.txt >test.txt
- A hozzászóláshoz be kell jelentkezni
Köszi, de ez valamiért ugyanazt csinálja.
Most fogtam és az uj.txt másoltam regi.txt-re. Így ugye minden azonos a két fájlban. Elvileg ekkor a test.txt-nek üresnek kellene lennie, hiszen minden adat azonos a két fájlban. Ezzel szemben ugyanaz történik mint a sed-es script esetében. A test.txt tartalma megegyezik az uj.txt tartalmával, azaz minden sor átmásolódott.
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
hat oooo ize. Nincs valami turpissag abban a fajlban? Rendes unios sorelemelesek vannak benne? Van az utolso sor vegen ENTER? Vagy en vagyok teljesen tompa ma reggel??
- A hozzászóláshoz be kell jelentkezni
Basszus!!!
Az első sorral baj volt! Akkor lehet az enyém is működik, majd megnézem :) (mondjuk csak kíváncsiságból, mert az awk-kal sokkal jobb! :D ) Az awk-os megoldást köszönöm, tökéletes!
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
Lehet, hogy rosszul közelítettem meg a problémát... mindazon által valóban teljes sort szeretnék törölni. Mivel sed-et óhajtottam használni így esett a választásom a második oszlopra, ahol csak számok vannak, ha úgy tetszik a sorok egyedi azonosítói. A többi oszlpban viszont van minden (szám, perjel, idézőjel, stb.), ami sed esetében nem a legszerencsésebb. :)
A fentebb leírt meglátásod -hogy miért nem megy- csak azért érdekes nekem, mert ha ezt csinálom:
sed -i 's/ /_/g' regi.txt
#!/bin/sh
for i in $(cat regi.txt); do
for j in $(echo $i | cut -d"|" -f2); do
echo $j
done
done
Akkor szépen egy oszlopban kiírja a számokat tartalmazó oszlopot. De sed-del így sem megy...
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
0. pont: mindig, minden korulmenyek kozott a shell valtozo-hivatkozasokat idezojelek koze tesszuk. Azt a kb 2 esetet a tizmilliobol, amikor nem, azt ugyis eszreveszi az ember.
1. Futtasd mar le kerlek ezt:
for i in $(cat regi.txt) ; do
echo "$i"
done
Es ha neked a regi.txt sorait egyben irja ki, akkor valami k nagy gaz van. Elvben azokat a sorokat ahol a szovegben barhol van pl szokoz, maris tobb sorra tordelve kell latnod.
2. A peldad pont azert hibas, mert az eredeti allomanyban *van* szokoz, ebben a tesztben pedig pont kicsereltel minden szokozt, igy nyilvan nem latszik, hogy szavakra tordeli a kulso for ciklus.
3. Raadasul a belso ciklus nem fog lefutni akkor, ha nincs mivel lefutni. Azaz amikor a kulso ciklus eppen "blabla" jellegu tartalmat allit be az i valtozo ertekekent, akkor a belso ciklus a feldolgozas utan ( echo | cut .. ) eredmenyekent pont epp semmit nem fog tartalmazni, igy aztan nem is latod, hogy nem csinal semmit. Nezd meg az alabbi ket peldat. Az elso esetben az echo altal eloallitott soremelest eldobja a shell, igy egyszer se fut le a ciklus, a masodik esetben kap egy nagyon egyertelmu ures stringet, es maris lefut.
$ for i in $( echo ) ; do echo ":$i:" ; done
$ for i in "" ; do echo ":$i:" ; done
::
$
- A hozzászóláshoz be kell jelentkezni