a következőt szeretném:
adott egy szöveg file amelyben engem a phn#-t megelőző sorok érdekelnek
az eredeti file így néz ki
valami szöveg van itt egy sorban
phn#
a phn#-hez hasonló címkét szeretnék a "valmi szöveg van itt egy sorban"
elejére beszúrni.
valahogy így
nam#valami szöveg van itt egy sorban
phn#
tehát nem új sorban, hanem beszúrni a matching sort megelőző sor eléjére.
Eddig sed-el kisérleteztem nem sok sikerrel.
sed '/adr#/i nam#' filename.txt
Ez nem beilleszti az előző sor elejére, hanem új sort hoz létre és abba írja nam#-t
köszönöm
- 8773 megtekintés
Hozzászólások
sed /"ide"/s/^/"ezt"/
- A hozzászóláshoz be kell jelentkezni
Ez nekem abba a sorba szúrja be a kivánt szöveget amelyikben a phn# van, és nem az
azt megelöző sor elejére. De legalább beszúrja valahová és nem új sort hoz létre.
ez lesz belőle
nam#adr#
- A hozzászóláshoz be kell jelentkezni
sed 's/phn#/"valami szoveg van itt egy sorban" \1 /g'
- A hozzászóláshoz be kell jelentkezni
Ez nem igazán müxik nekem.
ez jön vissza
sed: -e expression #1, char 47: invalid reference \1 on `s' command's RHS
Nekem az aktuális sort (változó tartalmú) kell megcímkéznem a nam# címkével, akkor ha az aktuális sort követő sor phn# címkével kezdődik.
- A hozzászóláshoz be kell jelentkezni
sed 'N; /\nphn#/s/^/nam#/' filename.txt
- A hozzászóláshoz be kell jelentkezni
Ez szintén csak a phn# sorba szúrja be a nam#-et, és nem az azt megelőzőbe!
- A hozzászóláshoz be kell jelentkezni
Biztos? nem ezt akarod? mert nekem így működik.
GNU sed version 4.2.1
cat filename.txt
valami szöveg van itt egy sorban
phn#
sed 'N; /\nphn#/s/^/nam#/' filename.txt
nam#valami szöveg van itt egy sorban
phn#
- A hozzászóláshoz be kell jelentkezni
Szerintem is ezt akarta, így nálam te nyertél! :)
- A hozzászóláshoz be kell jelentkezni
És tesztelted? Mert szerintem nem jó.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Teszteltem és jó.
- A hozzászóláshoz be kell jelentkezni
cat demo.txt
alma
valami szöveg van itt egy sorban
phn#
körte
valami más szöveg van itt egy sorban
phn#
szilva
sed 'N; /\nphn#/s/^/nam#/' demo.txt
alma
valami szöveg van itt egy sorban
phn#
körte
nam#valami más szöveg van itt egy sorban
phn#
szilva
Tehát nem jó.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
OK, igazad van, csak egyszer csinálja meg.
- A hozzászóláshoz be kell jelentkezni
ez válasz akart lenni az előzőre, de hozzászólás lett, törölni nem tudtam
- A hozzászóláshoz be kell jelentkezni
ha awk is johet:
#!/usr/bin/awk -f
BEGIN {
ins="beszur";
prevline="";
}
{
if( $1 == "phn#" ) printf("%s",ins);
if( NR > 1 ) printf("%s\n",prevline);
prevline = $0
}
END {
printf("%s\n",prevline);
}
- A hozzászóláshoz be kell jelentkezni
Jönni jöhet bármi megoldás, mert már a hajam is kihúllik lassan.
köszönöm, bár még nem sikerült életre lehelnem a scriptet.
- A hozzászóláshoz be kell jelentkezni
Mi a problema ?
Bemasolod egy fajlba(pl:insert.awk), adsz neki megfelelo jogosultsagot (chmod 755 insert.awk), azutan lefuttatod: insert.awk file.txt
Feltetelezve, hogy /usr/bin/awk helyes utvonal.
- A hozzászóláshoz be kell jelentkezni
$ sed /^phn#/\i#nam filename.txt
- A hozzászóláshoz be kell jelentkezni
Ez szintén egy üres sort csinál a phn# címke után, majd oda
teszi a nam# címkét!
- A hozzászóláshoz be kell jelentkezni
Pontosan azt csinálja, amit akarsz. Milyen sed-et használsz?
- A hozzászóláshoz be kell jelentkezni
sed version 4.2.1
- A hozzászóláshoz be kell jelentkezni
Bocs, kicsit félreértettem, mit szeretnél, most alaposabban elolvastam. Amit írtam, ugyan nem azt csinálja, amit te szeretnél, de biztosan nem is azt, amit írtál rá. A címke elé tesz be egy sort, és abba teszi be a '\i' után megadott címkét. Neked persze nem egészen ez kell...
- A hozzászóláshoz be kell jelentkezni
Akarom mondani a phn# címkével kezdődő sor előtti sorba szúr be egy új sort a nam# címkével.
- A hozzászóláshoz be kell jelentkezni
Én józan paraszti ésszel a következőképpen csinálnám:
Beolvasnék egy sort egy változóba
Ciklus indul EOF-ig
Beolvasnám a következő sort egy másik változóba
Ha a 2. változó elején ott a keresett string, az első változó sorát megfűszerezem a kívánt szöveggel
Első változó kiírása a kimeneti fájlba
Első változó legyen egyenlő második változó tartalmával
Ciklus vége
Második változó kiíratása a kimeneti fájlba
A szükséges vizsgálatokat (pl. van-e min. 2 sor) közben el kell végezni
openSUSE 12.2, vagy ami éppen jön.
- A hozzászóláshoz be kell jelentkezni
Igen pont ezt szerettem volna megúszni. És ezért szerettem volna egy egyszerű sed-es megoldást.
- A hozzászóláshoz be kell jelentkezni
~3 és fél óra alatt megírhattad volna így is :D
Persze elegánsabb lesz a sed-es megoldás, ha majd valaki kitalálja...
openSUSE 12.2, vagy ami éppen jön.
- A hozzászóláshoz be kell jelentkezni
Hát, én 10+ éve vagyok az iparban, de a multiline sed scripteket nem tudtam magamévá tenni ez idő alatt se. Isten áldja az awk-t! :)
- A hozzászóláshoz be kell jelentkezni
A fenti awk-os pont igy mukodik (gyk: prevline: elozo sor :) )
--
My gold plated butt-plug business is being sued by Apple.
Apparently they have a patent for overpriced crap for arseholes.
- A hozzászóláshoz be kell jelentkezni
Ezt a valaszt nem ertem. Mit szerettel volna meguszni? Ezt az algoritmust kell megcsinalni sed-del is. Ami nehezites, hogy kollega mindenfele valtozokrol beszelt, amije a sed-nek nincs. Ami konnyites, hogy van neki egy pattern space es egy hold space nevu terulete, ami kello fantaziaval felfoghato ket valtozonak. Javaslom a man 1 sed olvasgatast, kulonos tekintettel a nagybetus sed parancsokra, kb 4 vagy 5 van beloluk (sorban: D, G, H, N, P - ok, 5 db) es az x parancsra. Elkepzelheto, hogy szukseged lehet a cimke-kezelo parancsokra is (b, t, : parancsok), esetleg osszetett sed parancsokra ( { es } ), netan keresest cimkent hasznalni, esetleg negalt cimzest hasznalni.
Itt lejjebb mintha lenne valami hasonlo, most nincs nagy hangulatom kitesztelni, de persze ha jo es megerted, mar megerte.
- A hozzászóláshoz be kell jelentkezni
Ami nehezites, hogy kollega mindenfele valtozokrol beszelt, amije a sed-nek nincs.
Senki nem állította, hogy sed-el kell megoldani!
A kérdés felvetésben a kérdező azt közölte, hogy Ő eddig sed-el próbálkozott.
Én csak az elvet írtam le.
A sed-hez fongom nincs, úgyhogy így tudtam csak "segíteni". :)
Peace
openSUSE 12.2, vagy ami éppen jön.
- A hozzászóláshoz be kell jelentkezni
Nyugi, en nem teged baltaztalak le, hanem a kerdezot :-) Az altalad idezett mondat utan jeleztem is neki, hogy amit te nagyon helyesen valtozokent irtal le, azt az igenyelt nyelvben milyen neven keresse.
(Es amugy de, van aki sed-rol beszelt - maga a kerdesfeltevo a cimben ;-) .)
- A hozzászóláshoz be kell jelentkezni
sed '/phn#/i nam#' filename.txt
oppsz, most olvasom, hogy a szöveg elé kell a nam#, ez pedig a szöveg és a phn# közé teszi. bocs.
- A hozzászóláshoz be kell jelentkezni
Nem szép, nekem ez jött ki:
sed -r 's/^phn#/phn#/; T ment; x; s/(.*)/nam#\1/; b; : ment; x; 1 d; $ x;' demo.txt
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Szerintem POSIX sed-ben nincs nagybetus T parancs (csak t). Es milyen trukkos az onmagara csere, hogy a felteteles elagazas mukodhessen :-)
- A hozzászóláshoz be kell jelentkezni
A futás két ágát fel lehet cserélni, s akkor jó a kis 't' is akár. Nekem GNU sed-em van, így ennek a manualját olvastam.
sed-4.2.1-10.fc17.x86_64
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
a fenti, sajat peldaddal ez a megoldas sem jo.
alma
nam#valami szo van itt egy sorban
phn#
korte
nam#valami mas szo van itt egy sorban
szilva
egy phn# hianyzik a szilva felett
- A hozzászóláshoz be kell jelentkezni
Igaz. Javítottam:
sed -r 's/^phn#/phn#/; T ment; x; s/(.*)/nam#\1/; b; : ment; x; 1 d; $ { p; x; }' demo.txt
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Már csak azt nem tudom, hogy ha már egyszer belenéz az ember a doksiba, és *semmi* szerepe nincs, akkor miért használ valaki ilyen-olyan (nem-szabványos) bővítményeket
- ha (.*) helyett \(.*\) szerepelne, akkor nem kellene a GNU-specifikus -r opció sem, simán menne e nelkul (ezt a formát azért kell tudni, mert a grep (-E nélkül is) tudja pontosan ugyanúgy, néha pedig jól jön az ilyesmi)
- meg ugye a T parancs a t helyett :-)
De hogy a ne csak a szájam járjon, itt az én megoldásom. Ezt bele egy fájlba, és hadd szóljon:
#nothing but an important comment
1h
2,${
/^phn#/{
x
s/^/nam#/
x
}
x
p
}
${ x ; p ; }
Az a megjegyzés sor tényleg szükséges, de ha nem ismered ezt a non-documented, de a gnu-sedben is működő dolgot, akkor adj át a sednek egy -n opciót is.
Agyon nem volt tesztelve. de úgy kb. stimmel.
- A hozzászóláshoz be kell jelentkezni
Azért nem escape-eltem a zárójelet backslash-sel, mert szerintem így jobban olvasható a kód. Értem én, hogy jó a hordozhatóság, csak akkor meg minek fejlődjünk? Éppen ez az oka annak, hogy én a Bash hülyeségeit is kihasználom, ha már egyszer implementálták azokat. Simán le merek írni Bash scriptben olyasmit, hogy ((variable++)).
Mindezek mellett természetesen a hordozhatóság mellett is szólnak bőven érvek.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
A jobban olvashatosaggal kb egyetertek, de ha egyszer a nyelvben ezt ugy kell irni, akkor ugy kell irni. (Ez hasono, mint a muszaj, es a hulye.)
Ami miatt en altalaban ugrok az ilyesmire az az, hogy ritkan van leirva a teljes kornyezet - itt ugyan a sed le volt irva, de a futtatokornyezet (tehat az oprendszer) nem. Azaz valoszinuleg igaz, hogy Linux alatt akar az illeto ilyesmit, de egyaltalan nem biztos. (Speciel ha valahol az szerepel, hogy shell-script, akkor en nem bash-t feltetelezek, meg akkor sem, ha tobbsegeben arrol van szo - legalabbis a hupon.)
Es hogy mennyire nem mindegy a hordozhatosag, arra jo pelda, amikor bash-rol dash-ra csereltek (tan Debianban?) az alapertelmezett shellt, es egy halom regebben, figyelmetlenul megirt script elkezdett nem (jol) mukodni.)
- A hozzászóláshoz be kell jelentkezni
Ezt is értem, csak akkor valóban minek van bash, GNU sed, gawk és a többiek. Ami a Debiant illeti, vagy át kell írni a scripteket, vagy visszacserélni a default shellt bash-re, de talán a legegyszerűbb, ha a script elején megmondjuk, mi legyen az interpreter, aminek futtatnia kellene. Én itt mindig bash-t mondok, nem pedig sh-t, arról nem is beszélve, hogy Fedorán bash a default shell, nem használok Debiant. :)
Tehát én továbbra is használom azon eszközöket, amelyek a rendelkezésemre állnak, hiszen úgy gondolom, azért vannak, hogy használjam, s nem azért, hogy sóvárgó tekintettel nézzek rájuk, majd egy sh kompatibilis megoldással megkerüljem.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
KAMINGAUT
Én is csak akkor onanizálok azzal, hogy a (k)sh egye a szkriptet, amikor itt kóricálok (elvégre akkor van idő), amikor valamit gyorsan kell csinálni - és mi nem olyan? - akkor szemrebbenés nélkül vetem be a legbashonlybb trükköket is azon az alapon, hogy ha a shebang megléte mellett se tehetem meg ezt külön aggodalom nélkül, akkor akár perl vagy tk szkriptet se írjak soha.
/KAMINGAUT
- A hozzászóláshoz be kell jelentkezni
Kellene ket egymas alatti rekordot is latni, de nekem igy elso korben ez ugrott be:
awk '/^phn#/ { next; } { print "nam#" $0 }' file.txt > file2.txt
Probalj meg egy anonimizalt, de a fajl szerkezetet halalpontosan tukrozo peldat adni. Ha peldaul a "valami szoveg" ket soros, akkor olyan is legyen, ha van a rekordok kozt ures sor, az is legyen benne. Igy nagyon nehez okosat mondani.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal
- A hozzászóláshoz be kell jelentkezni
Nem jó, amit írtál. Nem az a feladat, hogy a phn# kezdetű sorokat nyelje el, s mindem más sor elé pedig szúrja be a nam# stringet.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Jujj, tenyleg. Akkor a next ele kell egy print $0; elnezest. Most elmegyek hamut szorni a fejemre.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal
- A hozzászóláshoz be kell jelentkezni
Az a gond, hogy ettől még ugyanúgy beszúrod azokba a sorokba is a nam# stringet, amelyek után nincs ott a marker. Ugye a feladat az, hogy csak a markert megelőző sorokba kell a beszúrás.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Mint irtam is, nincs leirva a kornyezet. Ha a rekordok ketsorosak, es nincs koztuk elvalaszto, akkor az en megoldasom is mukodhet a definicionak megfeleloen. Nem pontos a definicio, nincs pelda megadva, igy eltem az iroi szabadsag adta jogommal :-)
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal
- A hozzászóláshoz be kell jelentkezni
Mellébeszélés. :)
echo -e 'elso sor\nmasodik sor' | awk '/^phn#/ { print $0; next; } { print "nam#" $0 }'
nam#elso sor
nam#masodik sor
A specifikáció lényege itt van:
tehát nem új sorban, hanem beszúrni a matching sort megelőző sor eléjére.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
A feladatkiiras erre a peldara vonatkozott:
$ echo -e 'valami szöveg van itt egy sorban\nphn#' | awk '/^phn#/ { print $0; next; } { print "nam#" $0 }'
nam#valami szöveg van itt egy sorban
phn#
A kimenet tokeletesen megegyezik az elvarttal. Test passed. Pontosan mi is a kerdes?
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal
- A hozzászóláshoz be kell jelentkezni
Ja, ha így nézzük, akkor van egy egyszerűbb megoldásom is:
echo -e 'nam#valami szöveg van itt egy sorban\nphn#'
Azért remélem, az érthető vol a kiírásból, hogy van egy szövegfile, abban vannak néha markerek, s a markert megelőző sor elejére kell beszúrni valamit, a többi sort érintetlenül kell hagyni.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Csak nem tudni, hogy hogy vannak a markerek... na mindegy.
Amugy ez is megoldhato belso olvasociklussal es ketsoronkenti pufferelt kiirassal, csak most nincs annyi idom foglalkozni vele.
--
Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal
- A hozzászóláshoz be kell jelentkezni
Persze, hogy megoldható. Születtek is rá megoldások. :)
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Álljon itt az utókornak egy perl egysoros megoldás:
perl -lne '$p="nam#".$p if /^phn#/;print $p if $.-1;$p=$_}{print' filename.txt
- A hozzászóláshoz be kell jelentkezni
Legyen itt akkor egy sok soros Python is (biztos lehet szebben is):
#!/usr/bin/env python
import sys
stdow = sys.stdout.write
stdin_iter = iter(sys.stdin)
try:
prev = next(stdin_iter)
except StopIteration:
prev = None
for line in stdin_iter:
stdow('nam#' + prev) if line.rstrip('\n') == 'phn#' else stdow(prev)
prev = line
if prev:
stdow(prev)
Btw. ez a Perl egysoros nem működik rendesen, az utolsó sort lenyeli.
Szerk.
♲♻♲
- A hozzászóláshoz be kell jelentkezni
Csak úgy az utókornak, ha valaki nem ismerné, egy kis sed "gyorstalpaló":
- A hozzászóláshoz be kell jelentkezni
Ha mégis sed-et használnál:
sed ":a;N;$!ba;s/\n\([^\n]*\)\n\(phn#\)/\nnam#\1\n\2/g"
Némi magyarázat:
:a :
label
N :
Új sor
$!ba :
Amíg nincs(!) vége($) a fájlnak, (b)ranch, vagyis nyomás az a labelhez.
Innentől nem soronként, hanem egyben manipulálható az egész fájl.
- A hozzászóláshoz be kell jelentkezni
Az egyben manipulalahatosag jo otlet, felteve, hogy nem utkozol korlatokba. A POSIX specifikacio osszesen annyit ir elo, hogy legalabb 8192 byte meretu kell legyen a 'pattern space' illetve a 'hold space'. Innentol pedig mar a megvalositason mulik, hogy hajlando-e mondjuk dinamikus memoriafoglalassal dolgozni a vegtelensegig. (Nyilvan valamennyire rugalmasnak kene lennie, hisz lehetnek szep hosszu sorok a fajlban, ennek ellenere mivel a sed pont arra lett kitalalva, hogy ne kelljen beolvasni egy fajlt teljes egeszeben, itt azert en erzek nemi ellentmondast.)
- A hozzászóláshoz be kell jelentkezni
Gondoltam rá, hogy megemlítsem a memóriahasználatot, amit a bemenet és a kimenet összege, de 8K-s pufferrel még nem találkoztam. Konkrétan most kipróbáltam a 4.2.1-es GNU sedet egy 380 megás fájllal, és működött.
- A hozzászóláshoz be kell jelentkezni