A bash shell függvény használata az AWK belsejében

Használható valahogy az AWK belsejében a bash függvény?

Példa fájl (karakterlánc, int, int , int)

Mike 247808 247809 247810 

Megpróbálja átalakítani az értékeket tizedestől hexadecimálissá.

A .bashrc vagy shell szkriptben.

$ awk "{print $1 ; d2h($2)}" file awk: calling undefined function d2h input record number 1, file file source line number 1 

Válasz

Próbálja használja a system() függvényt:

awk "{printf("%s ",$1); system("d2h " $2)}" file 

Az Ön esetében system hívja meg d2h 247808, majd csatolja a parancs kimenetét a printf kimenethez:

Mike 3C800 

SZERKESZTÉS:

Mivel system a sh szót használja a bash Nem találok módot a .bashrc elérésére. De továbbra is használhatja a jelenlegi bash szkript függvényeit:

#!/bin/bash d2h() { # do some cool conversion here echo "$1" # or just output the first parameter } export -f d2h awk "{printf("%s ",$1); system("bash -c "\""d2h "$2""\""")}" file 

2. SZERKESZTÉS:

Nem tudom miért, de ez nem működik az Ubuntu 16.04-en. Ez furcsa, mert korábban az Ubuntu 14.04-en működött.

Megjegyzések

  • Ez akkor működhet, ha d2h futtatható fájlok voltak, de nem, ha ‘ sa ” függvény definiálva vagy .bashrc vagy shell szkriptben “.
  • @MichaelHomer igen, igazad van. Megjegyzésének köszönhetően rájöttem, hogy válaszoltam a senki által feltett kérdésre. De találtam egy módszert a jelenlegi szkript függvényeinek használatára (és esetleg más szkriptekről a source útján), de ‘ f ábra miért nem ‘ működik a .bashrc.
  • Ez ‘ s egy parancsinjekciós sebezhetőséget is jelent, mivel a $2 tartalmát végül shell kódként értelmezik.
  • Ha export -f d2h nem működik ‘ t, ezt úgy is megteheti, mint a ksh / zsh esetében: (\ \ 42 és \ 47 az egyszerű és dupla idézőjelek menekülési kódjai) CODE=$(typeset -f d2h) awk ' { system("bash -c \47eval \42$CODE\42; d2h \42"$2"\42\47") }'

Válasz

Az awk-ból meghívhatja a bash-t, és használhatja annak kimenetét. Ez a teljesítmény szempontjából nyilvánvalóan veszélyes, ha túl gyakran fordul elő. A man oldal idézése:

command | getline [var] 

Futtassa a kimenetet a $ 0 vagy a var változóba,

parancs egy bash szkript lenne, amely tartalmazza a függvény definícióját és végrehajtja a függvényt.

Válasz

A tizedestől hexadecimálissá konvertálás awk nagyon jól meg tudja csinálni magát. És megadhat egy awk függvényt:

 function d2h(d) { return sprintf("%x", d) }  

Most, hogy megválaszoljam a kérdést általános esetben, az awk futtatásához a bash function, akkor awk kell egy bash shell végrehajtásához, amely bash a függvény definíciójának értelmezése és a függvény meghívása az awk által kivont érték argumentumként való átadásával.

Nem triviális.

bash támogatja a függvények exportálását a környezeten keresztül, így a bash későbbi meghívásaiban elérhetővé válik, így ez az egyik út a bash függvény meghatározása, amelyet awk hívott meg:

export -f d2h 

A awk parancs végrehajtásának egyetlen módja (bash h ere) a system("cmd") vagy print... | "cmd" vagy "cmd" | getline. Minden esetben a awk futtat egy héjat annak értelmezésére, hogy cmd, de sh, nem bash. Tehát fel kell állítania egy parancssort sh számára, amely egy bash meghívás, amely egy bash parancssor a függvény meghívásához, ezért vigyázni kell az idézéssel:

export -f d2h <file awk -v q=""" " function shquote(s) { gsub(q, q "\\" q q, s) return q s q } {print $1; system("exec bash -c "\""d2h \"$1\""\"" bash " shquote($2))}" 

Ha a függvény kimenetét vissza akarja állítani a awk, vissza kell vezetnie egy csövön keresztül. Ehhez a iv id = “helyett a cmd | getline -t kell használni. 4be2d082e4 “>

(amicmd” stdout-t érintetlenül hagyja).

cmd | getline line egy sort tárol (szigorúan véve egy rekord , a rekordok alapértelmezés szerint sorok), tehát A teljes kimenet megszerzéséhez olyan esetekben, amikor több sorból áll, szükséged van egy hurokra, például:

 awk "... cmd = "exec bash -c "\""d2h \"$1\""\"" bash " shquote($2) output = "" while ((cmd | getline line) > 0) { output = output line RS } sub(RS "$", "", output) # remove the last newline ..."  

Ez azt jelenti, hogy egy sh és egy bash futtat a függvény minden egyes meghívásához , így elég hatástalan lesz. Ez még lényegesen hatástalanabb lenne, mint ha bash elvégezné az olvasást és az osztást egy while read loop:

(unset -v IFS; while read -r a b rest; do printf "%s\n" "$a" d2h "$b" done < file) 

Vegye figyelembe azt is, hogy a shellshock óta a bash exportál olyan funkciókat a környezeti változókba, amelyek neve: BASH_FUNC_d2h%%. Néhány sh megvalósítás, köztük mksh és a dash eltávolítás em újabb verziói > azok a környezeti változók a környezettől:

$ env "foo%%=bar" dash -c "printenv foo%%" $ env "foo%%=bar" mksh -c "printenv foo%%" $ env "foo%%=bar" zsh -c "printenv foo%%" bar $ env "foo%%=bar" bash -c "printenv foo%%" bar 

Tehát ahelyett, hogy a gyenge függvény-exportálási funkcióra hagyatkozna, átadhatja a függvény-meghatározást más módon is. Lehet egy szokásos nevű környezeti változón keresztül:

 BASH_FUNCTIONS=$(typeset -f d2h) awk " ... cmd = "exec bash -c "\""eval \"$BASH_FUNCTIONS\";" \ "d2h \"$1\""\"" bash " shquote($2) ..."  

Válasz

Próbálkozzon ezzel:

awk "{print $1 ; printf "%x\n", $2}" file 

AFAIK, nem használhat bash-t függvény az awk-ban, de csak egy szkript. Szükség esetén használhat egy awk függvényt is.

Válasz

A felhasználó által definiált bash függvény használata belül awk

Jogi nyilatkozat: Tudomásul veszem, hogy az OP nem ezt próbálja megtenni, de a Google a hozzám hasonló embereket is erre a válaszra vezeti.

Helyzet

Van egy bash szkripted, amely funkciókkal van rendezve (mert nem utálod magad vagy [a legtöbb munkatársat]), és ezeknek a funkcióknak legalább 1-nek hívjon másikat a awk belülről.

Megoldás

Script

#!/bin/env bash # The main function - it"s a sound pattern even in BASH main(){ # In the awk command I do some tricky things with single quotes. Count carefully... # The first $0 is outside the single quotes so it is the name of the current bash script. # The second $0 is inside the single quotes so it is awk"s current line of input. awk "{printf("%s. ", ++c); system(""$0" --do"); print $0}"<<-PRETEND_THIS_IS_AN_INPUT_STREAM and and well PRETEND_THIS_IS_AN_INPUT_STREAM } # functionized to keep things DRY doit(){ echo -n "doin" it " } # check for a command switch and call different functionality if it is found if [[ $# -eq 1 && $1 == "--do" ]]; then doit else main fi 

Output

$ ./example.sh 1. doin" it and 2. doin" it and 3. doin" it well 

megjegyzések

  • I képviseli Queens-t, Brooklynban nevelték ki

Válasz

Csak egy gyors példa a @HaukeLaging “s bemutatására command|getline:

  1. legyen a bemenet:
Dear friends my name is `id -nu` and today is `date "+%Y-%m-%d"`. 

ahol a shell szintaxist követjük, akkor a bemenetben

`command` 

jelöljük a inline parancsokat , amelyeket a végrehajtása.

  1. A soron belüli shell parancsot kibővíthetjük:
#!/usr/bin/gawk -f BEGIN { FS ="`"; } NF==3 { $2 | getline $2 } { print } 
  1. Használat (a szokásos chmod után):
$ expand-inline input Dear friends my name is jjoao and today is 2018-01-15. 

Válasz

Ez jó eséllyel jár.

cat ../logs/em2.log.1 |grep -i 192.168.21.15 |awk "{system("date"); print $1}" 

A rendszerfunkció lehetővé teszi a bash parancs elemzését az awk adatfolyamban.

Válasz

Ez a válasz a GNU awk esetén, de más verziók is megvalósíthatják ugyanazt a trükköt. Az elképzelés az, hogy mindaddig, amíg a cső jobb oldala pontosan megegyezik és nem “kilép”, az awk nem csukja be a csövet. De ha ez más, akkor új csövet nyit. Például, ha beírja:

awk "BEGIN{ shell= "/bin/bash" } { print $0 | "/bin/bash" } END { print "echo $a" | " /bin/bash" }" 

beírhatja:

a=5 echo $a 

és kapja meg a várt (?) választ 5: nem született új héj. De az END szakaszban beírtam egy extra helyet, így a cső RHS-je eltér, és új héj keletkezik, amelynek nincs értéke az a változónak (és így egy üres sort nyomtat a kilépéskor. Nem találom a dokumentációval, de a hosszú távú csövek használatának ajánlott módja megegyezik a következővel: tegyem a parancsot a BEGIN szakaszba egy változóban, és használd újra ezt a változót.

Felhasználó által definiált függvény átadása egy bash munkamenetnek akkor az újrafelhasználása az olvasó számára hagyott gyakorlat 🙂

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük