2010-02-09 4 views
17

Sto imparando awk e ho problemi a trasmettere una variabile allo script E a usarla come parte di un modello di ricerca regolare.Passare la variabile a awk e usarla in un'espressione regolare

L'esempio è inventato ma mostra il mio problema.

miei dati è la seguente:

Eddy  Smith  0600000000 1981-07-16 Los Angeles 
Frank  Smith  0611111111 1947-04-29 Chicago   
Victoria McSmith  0687654321 1982-12-16 Los Angeles 
Barbara  Smithy  0633244321 1984-06-24 Boston    
Jane  McSmithy 0612345678 1947-01-15 Chicago    
Grace  Jones  0622222222 1985-10-07 Los Angeles 
Bernard  Jones  0647658763 1988-01-01 New York   
George  Jonesy  0623428948 1983-01-01 New York   
Indiana  McJones  0698732298 1952-01-01 Miami    
Philip  McJonesy 0644238523 1954-01-01 Miami 

Voglio uno script awk che posso passare una variabile e quindi avere lo script awk fare una regex per la variabile. Ho ora questo script chiamato "003_search_persons.awk".

#this awk script looks for a certain name, returns firstName, lastName and City 

#print column headers 
BEGIN { 
    printf "firstName lastName City\n"; 
} 

#look for the name, print firstName, lastName and City 
$2 ~ name { 
    printf $1 " " $2 " " $5 " " $6; 
    printf "\n"; 
} 

io chiamo lo script come questo:

awk -f 003_search_persons.awk name=Smith 003_persons.txt 

restituisce il seguente, che è buono.

firstName lastName City 
Eddy Smith Los Angeles 
Frank Smith Chicago 
Victoria McSmith Los Angeles 
Barbara Smithy Boston 
Jane McSmithy Chicago 

Ma ora voglio cercare un certo prefisso "Mc". Potrei naturalmente indicarlo, ma voglio uno script awk che sia flessibile. Ho scritto quanto segue in 003_search_persons_prefix.awk.

#this awk script looks for a certain prefix to a name, returns firstName, lastName and City 

#print column headers 
BEGIN { 
    printf "firstName lastName City\n"; 
} 

#look for the prefix, print firstName, lastName and City 
/^prefix/{ 
    printf $1 " " $2 " " $5 " " $6; 
    printf "\n"; 
} 

io chiamo lo script come questo:

awk -f 003_search_persons_prefix.awk prefix=Mc 003_persons.txt 

Ma ora trova nessun record.

Il problema è il modello di ricerca "/^prefisso /". So che posso sostituire quel modello di ricerca con uno non regex, come nel primo script, ma supponiamo di volerlo fare con un'espressione regolare, perché ho bisogno del prefisso per essere veramente all'inizio del campo lastName, poiché dovrebbe essere, essendo un prefisso e tutto ;-)

Come faccio a fare questo?

+2

pulizia in corsia 5: sbarazzarsi di tutte le dichiarazioni nulli (trailing punti e virgola), il cambiamento printf "\ n "per stampare semplicemente" ", e cambiare printf $ 1" "$ 2 ecc. per stampare semplicemente $ 1, $ 2, ecc. –

risposta

16

si può provare questa uscita

BEGIN{ 
printf "firstName lastName City\n"; 
split(ARGV[1], n,"=") 
prefix=n[2] 
pat="^"prefix 
} 
$0 ~ pat{ 
    print "found: "$0 
} 

$ awk -f test.awk name=Jane file 
firstName lastName City 
found: Jane  McSmithy 0612345678 1947-01-15 Chicago 

sguardo al awk documentation di più. (e leggerlo dall'inizio alla fine!)

+0

Grazie, lo proverò a breve. –

+4

Nessuno di questi elementi di suddivisione è necessario perché l'utilizzo di nome = Jane nell'elenco di argomenti crea una variabile denominata "nome" con il valore "Jane" in modo da poter dire semplicemente "pat ="^"nome' in un FNR == 1 sezione. L'impostazione di variabili con "-v" è comunque preferibile sebbene non sia necessario aggirare le variabili non popolate nella sezione BEGIN. –

0

è richiesto? Sono sicuro che è abbastanza possibile in awk, ma non lo so, se hai solo bisogno di finire il lavoro, allora puoi provare. non sono sicuro di cosa sia esattamente quel delimitatore.

cut -d " " -f1-2,5 file | egrep '^regex' 
+0

awk è uno strumento elettrico che fa il lavoro di cut e grep combinati. quindi sì è possibile con awk. Vedi http://www.gnu.org/manual/gawk/html_node/Computed-Regexps.html#Computed-Regexps – ghostdog74

+0

Sono interessato alla soluzione awk per questo. Ma grazie. –

1

Dovresti essere in grado di utilizzare lo script originale invariato - $2 ~ name sta già facendo una ricerca regolare, quindi se chiami il tuo script con name=^Mc, restituirà i nomi che iniziano con "Mc" . In realtà questo non è un buon esempio, dal momento che Mc appare solo all'inizio del nome - se usi name=^Smith allora troverà gli Smiths ma non i McSmiths.

+0

Ma poi dovrei passare una regex (^ Smith) come parametro, e personalmente penso che sia un po 'brutto. –

5

modificare lo script per:

BEGIN { 
    print "firstName", "lastName", "City" 
    ORS = "\n\n" 
} 

$0 ~ "^" prefix { 
    print $1, $2, $5, $6 
} 

e lo chiamano come

awk -v prefix="Mc" -f 003_search_persons.awk 003_persons.txt 
+0

Bello! Il trucco '$ 0 ~"^"' è quello che stavo cercando. – fedorqui