sed - behelyettesítés változó értékével. Megoldva.

Fórumok

Ü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?

Hozzászólások

sed "s/szoveg/${VALTOZO}/" textfile.txt >newtextfile.txt

de el is hagyhatod...

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!)

VALTOZO="TEXT"
sed "s/szoveg/$VALTOZO/g" textfile.txt>newtextfile.txt

VALTOZO="TEXT"
export VALTOZO
sed 's/szoveg/'"${VALTOZO}"'/' textfile.txt >newtextfile.txt

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 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 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

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

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.”

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.

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 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...

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.

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

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

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
::
$