grep-sed-awk [megoldva]

Fórumok

Sziasztok.

Adott sok állományom, melyet létrehoztam.
Vannak bennük sorok, egyes sorok elején TAB, mások elején space.
Olyan sor is van, amely betű karakterre kezdődik.

Azon sorok elejére szeretnék illeszteni valamit, amelyek elején space vagy tab van, aztán 4 db numerikus karakter következik, majd egy space.

Szerintetek megoldható awk nélkül is?

---------

tehát ebből:

3582 sjefngkjsngkjse
TAB9467 jfnbjfdnbjldfbnj

ez:

Record 3582 sjefngkjsngkjse
Record 9467 jfnbjfdnbjldfbnj

Kösz szépen minden javaslatot

Hozzászólások

"Azon sorok elejére szeretnék illeszteni valamit, amelyek elején space vagy tab van, aztán 4 db numerikus karakter következik, majd egy space."
Eleje (^), whitespace (\s), numerikus ([0-9]).

Öszerakva:


$ echo -e ' 3582 sjefngkjsngkjse\n\t9467 jfnbjfdnbjldfbnj' | sed 's/^\s\([0-9]\{4\} .*\)/Record \1/ '
Record 3582 sjefngkjsngkjse
Record 9467 jfnbjfdnbjldfbnj
$

Nem annyira nehéz, bash tud c-style escapet is, ld. http://wiki.bash-hackers.org/syntax/quoting

There's another quoting mechanism, Bash provides: Strings that are scanned for ANSI C like escape sequences. The Syntax is $'string' where the following escape sequences are decoded in string:

\a terminal alert character (bell)
\b backspace
\e escape (ASCII 033)
\E escape (ASCII 033)
\f form feed
\n newline
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\' single quote

Nem tudom, nekem a \t es tarsait nem szokta mindig minden program feltetel nelkul elfogadni, futottam mar par sikertelen kort. Talan ez nem is igazan bash cucc, hanem a progitol fugg.

Szerk: megneztem az oldalt. Nahat, hogy ezek a bash fejlesztok milyen trukkos fiuk... Maskor is lattam mar dollar-idezojel meg dollar-aposztrof sztringeket, de sose gondoltam, hogy van ennyire specko jelentesuk is.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. 

Valasz.

1) Benne volt az elozo hozzaszolasomban: mert hordozhatobb. Tudom, hogy a Linuxokban alapban levo GNU-sed ugyanugy erti a \s-t, mint a \t-t peldaul, de egyreszt mas sed verziok (es nagyon sok RE-megvalositas) ezt nem tamogatja, es tudtommal a POSIX-szabvany sem emlegeti (*). (En ugy tudom, hogy a Perl volt az, ahol egyaltalan elkezdett jelentessel birni, es onnan szivargott at a GNU-sedbe.)
2) Raadasul azt szeretik kenyelmesen elfelejteni, hogy a \s nem csak szokoz es tabulator, hanem ezenkivul kocsivissza, soremeles, valamint lapdobas karakter is lehet(ne) - speciel, hogy a fuggoleges tabulatort mi a fraszert nem vettek be, azt nem ertem. Az eredeti feladat viszont egyertelmuen szokoz es tabulator volt.

Egyaltalan nem nehez tabot bevini, csak
a) megfelelo shell kell hozza (pl. rendes sh-ban, ksh-ban semmi gond nincs vele)
b) tudni kell azt a shellt hasznalni (legtobb shell eseten vagy \, vagy pedig - pl. a bash-nal - ^V kell ele, ha ilyen huncutabb karaktert akarsz begepelni)

(*) "The interpretation of an ordinary character preceded by a backslash (\) is undefined, except for" - no es a kivetelek kozott nem szerepel se az a, se az n, se a t. Es persze az s sem. ( http://pubs.opengroup.org/onlinepubs/7908799/xbd/re.html ) Tehat erre epiteni botorsag.

En foleg a b) pontra gondoltam, amikor azt irtam, nehezebb. Minden olyan shellben nyugos, ahol completion van, mert az a tab billentyun ucsorog.

Egyebkent meg ha jol tippelek, akkor talan a PCRE konyvtar hozza magaval az ilyen regexpek ertelmezeset, mert ami azt hasznalja, ott a \s -nek van ertelme.

Ezen felul, en nem latom mindig ertelmet hordozhato kodot irni. Van egy akut feladat, arra kell adni egy akut megoldast, utana valoszinuleg a script a budos eletben soha tobbet elo nem kerul. Persze, egy reusable kodnal, vagy egy olyan jellegu feladatnal, ami tipikusan arrol szol, hogy tobb rendszeren is fusson, ott igen, ott kell, sot hasznos.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. 

> Minden olyan shellben nyugos, ahol completion van, mert az a tab billentyun ucsorog.

Ez se igaz. man ksh, az ESC-en van a kiegeszites (ESC-ESC, ESC-* es ESC-= - ha emacs modban vagy.)

A PCRE-ben nyilvan igazad lehet, hiszen meg a neve is ez: Perl-Compatible-RegEx. Pont ezt mondtam, hogy a metaszimbolumokat a Perl vezette be. Raadasul tudtommal az awk es a grep (valamint a vi, expr, stb) nem ismeri ezeket a metaszimbolumokat meg Linux alatt sem. Tehat igy-is-ugy-is meg kell szokni megtanulni hogy pl. a \s helyett azt kell irni, amit en irtam (felteve, hogy az kell nekunk). (Ellenoriztem. vim nem tudja, gawk nem tudja, gnu-grep nem tudja. Most epp GNU-expr nincs a kezem ugyeben, de 99,9%, hogy az se tudja.)

Akut problemara azonnali valasz kell - ez igaz. Node ha mar valaki kerdez, akkor akar olyan valaszt is adhatok, ami nem csak ebben a masodpercben hasznos, hanem 10 perc mulva is. Tehat adni neki egy jo valaszt az jo, adni neki egy jo es hordozhato valaszt, az meg jobb. Raadasul megtanulni azt, hogy hogyan kell bevinni a specialis karaktereket (\ vagy ^v elotte) az mindig jol jon, ugyanis van helyzet, amikor be *kell* ilyet tudni gepelni.

"vagy ^v elotte"

Amit már csak azért is jó tudni, mert az első tapasztalat azt mondaná, hogy a vi(m) nem képes akármilyen karaktert befogadni, vagy egyszerre kezelni a szóközre autokonvertált TAB-ot és az igazi TAB karaktert - aztán ha második ránézésre elfogadja az ember, hogy van Ctrl-V, máris szabadabban lélegzik.

I----------------------I
I Köszönöm szépen! I
I----------------------I

cat csupasz_nyersanyag.txt | sed 's/^\s\([0-9]\{4\} .*\)/XXXcim: \1/ '>csinalni

...aztán a csinalni nevű szöveges anyagomat csplittel szétszabdaltam, végül kinyertem belőle mindent amit akartam, aztán egy csv állományba írtam mindent, 15 MB-nyi adathalmazt, 230 darab fájlon.

Te raktad fel a koronát az egészre.

Tulajdonképpen gyötrelmesen siralmas vagyok a sed és a grep illesztéses használatánál, illő enne leülnöm és végigrágnom magamat rajta.
Nemsokára végigtanulmányozom, miért is működött amit írtál.
:)

---
--- A gond akkor van, ha látszólag minden működik. ---
---

ok.
a "< file" fordított átirányításokhoz azért nem szoktam még hozzá, mert sok esetben 10-15 csatornát (|) használok, soxor
\|
jelekkel zárva a sorok végét.
Eddig ez áttekinthető volt, különsen awk-nál, ahol rengeteg lenne egy sorban mazsolázni, mit hagytam ki.

A csplittel szétcincált állományokból viszont sikeresen rákerestem a megfelelő stringekre, nos, itt használtam a "<" jelet rendesen:


csplit -z -f ./TEMP csupasz_nyersanyag.txt /'XXXrekord'/ {*}

for i in ./TEMP*
do
grep -w ^XXXnev $i >nev.temp
read pre nev <./nev.temp
echo $nev>>nev.oszlop
rm ./nev.temp

grep -w ^XXXcegnev: $i >cegnev.temp
read pre cegnev <./cegnev.temp
echo $cegnev>>cegnev.oszlop
rm ./cegnev.temp

grep -w ^XXXcim: $i >cim.temp
read pre cim <./cim.temp
echo $cim>>cim.oszlop
rm ./cim.temp

grep -w ^XXXTelefon: $i >telefon.temp
read pre telefon <./telefon.temp
echo $telefon>>telefon.oszlop
rm ./telefon.temp

grep -w ^XXXMobil: $i >mobil.temp
read pre mobil <./mobil.temp
echo $mobil>>mobil.oszlop
rm ./mobil.temp

grep -w ^XXXEmail: $i >email.temp # kettospontot kirakni...
read pre email <./email.temp
echo $email>>email.oszlop
rm ./email.temp

done

rm ./TEMP*
rm index.*

---
--- A gond akkor van, ha látszólag minden működik. ---
---