Egy kis AWK segítség kérés

Sziasztok,

Próbáltam AWK scriptet írni, de nagyon nem ment, ezért megkértem a ChatGPT-t, hogy írja meg nekem. Az adott feladat, egy program kimenetét feldolgozni az alábbi módon:

1. sor nem kell, átlépjük
minden további sorban az első két mező elválasztása " " szóköz mentén, míg az utolsó rész ami egy - jel után van legyen a harmadik mező.

példa:

pelda.txt

    Header1 Header2 - Egyszó
Valami     Szöveg - Több szó is lehet
Másik Sor - Még egy hosszabb kifejezés - van benne kötőjel

A hozzátartozó AWK script:

awk 'NR > 1 { 
    # Az első két szót (szöveg1, szöveg2) elválasztjuk
    split($1, arr1, " ");  # A szöveg1-t és szöveg2-t első lépésben szétválasztjuk
    split($2, arr2, " ");  # A szöveg2 után is szétválasztjuk
    # Azokat az adatokat, amik a "-" után vannak, egy változóba tesszük
    text = substr($0, index($0, " - ") + 3)  # A "-" utáni szöveget változóba tesszük
    print arr1[1],",",arr2[1], ",", text  # Kinyomtatjuk az első két szót és a kifejezést
}' pelda.txt

Lehet ezt egyszerűsíteni, vagy "jóvanazúgy"? :)

Hozzászólások

Ha működik, és összesen 5 sor (kommentek nélkül számolva), akkor minek hozzányúlni? Teljesítmény probléma van vele?

Vagy nem működik? Nem próbáltam ki.

Működik, kipróbáltam. Nem a sorok számával van gondom, a teljesítménnyel sem, mert 2-3 sort kell feldolgoznom összesen csak. Arra gondoltam csak, hogy egy AWK guru elküld a francba és ír nekem egy sorosat ha lehetséges :)

Ezek szerint a ChatGPT tényleg ügyes, amúgy teljesen magyarul beszéltem vele és fogalmaztam meg mit szeretnék és második nekifutásra megalkotta ezt. Ezek szerint nem kell se bonyolítani, se egyszerűsíteni.

Szerkesztve: 2025. 01. 12., v – 20:48

Ez valami iskolai feladat, hogy mindenkepp AWK kell hozza? Ha jo mas is, miert nem irod meg olyan scriptnyelven, amihez ertesz?

Mindenesetre a kod a kommentekkel szamomra ertheto, pedig nem vagyok awk guru. Pythonban, PHP-ben, JS-ben, meg egyeb scriptnyelveken sem nezne ki sokkal masabban (esetleg regexpet hasznalhatsz, az egyszerusithetne).

"^[^ ]+ [^-]+-.*$" illeszkedik ha jol ertelmeztem, esetleg elnevezgetve a reszeit: "^(?P<first>[^ ]+) (?P<second>[^-]+)-(?P<third>.*)$". Valami ilyesmi, nem probaltam ki. Nem biztos, hogy olvashatobb.

szerk: Ja, az LLM-ek tudasa fugg a tanitohalmazbeli meretuktol. Sokkal tobb Python meg JavaScript kod van, mint AWK, kodot is jobbat general. Ugyanez az oka annak, hogy angol promptra jobb valaszt general, mint magyarra - kb. 1000* tobb szoveget adtak neki angolul, mint magyarul.

A strange game. The only winning move is not to play. How about a nice game of chess?

Nem iskolai, csak gondoltam ha már van awk akkor megírom abban (de nem vagyok guru). Direkt nem akartam scriptnyelvet használni. Egy egyszerű bash scriptben kell egy program kimenetét kiszednem, hogy utána táblázatba tudjam rakni. Sima sed-et meg cut-ot nem akartam egymásba ágyazni.

Valami szkriptet mindenképp kell használj erre, ha nem fordított nyelven írt natív bináris kóddal dolgozol.

Valószínű ez az awk-os megoldás (vigyázz, az awk is szkritnyelv) még gyorsabban fut, mint ha Bash-ban, vagy ksh/dash-ban csinálnád, head, cut, kombóval, mert nem kell több folyamatot forkolnia a rendszernek, csak az awk folyamatát egyszer, és az megoldja belül.

Talán ha Perl-be, vagy Lua-ba átírod, az gyorsabb lesz, mert azok tudnak JIT-et, de ha nem olyan óriási a feldolgozandó fájl, akkor nem hiszem, hogy nagyon sokat nyernél vele. Ezek is szkriptnyelvek természetesen. Leggyorsabb nyilván C-ben lenne, de az megint csak akkor éri meg, ha valami óriási adat miatt kell az a plusz sebesség, vagy ezt a toolt annyira gyakran használnád. Ha csak 1-2× kell, akkor tökéletes ez az awk-os megoldás, csodálkozok is, hogy ezt a Zalyíí saját kútfőből ilyen f4×ányosan tető alá hozta, nem nézném ki belőle.

The world runs on Excel spreadsheets. (Dylan Beattie)

cat pelda.txt|awk -F ' +' 'NR>1{printf "m1=%s m2=%s m3=%s\n",$1,$2,substr($0,match($0,"- *")+RLENGTH)}'
m1=Valami m2=Szöveg m3=Több szó is lehet
m1=Másik m2=Sor m3=Még egy hosszabb kifejezés - van benne kötőjel

A program a szóközkötőjelszóköz utáni részt teszi be a text változóba, nem pedig a szóköz utáni részt. Egy sorban ugyanez:

if (NR > 1) { printf("%s , %s , %s\n", $1, $2, substr($0, index($0, " - ") + 3)) }

Ebben ki van használva, hogy alapértelmezetten az FS (field separator) szóköz, így $1 és $2 adott.

Az a jó benne, hogy csak a bemenetet írtad le, a  kivánt outputot nem.

Szerintem awk helyett erre inkább sed való:

$ sed -n -E '2,$s/^\s*(\S+)\s+(\S+)\s*-\s*(.*)$/\1, \2, \3/p' <<EOF
    Header1 Header2 - Egyszo
Valami     Szoveg - Tobb szo is lehet
Masik Sor - Meg egy hosszabb kifejezes - van benne kotojel
EOF
Valami, Szoveg, Tobb szo is lehet
Masik, Sor, Meg egy hosszabb kifejezes - van benne kotojel

$ grep -c egy$ word.list
100