2010-02-09 11 views
17

Uczę się awk i mam problem z przekazaniem zmiennej do skryptu i użyciem go jako części wzorca wyszukiwania regex.Przekazywanie zmiennej do awk i używanie jej w wyrażeniu regularnym

Przykład jest wymyślny, ale pokazuje moje probem.

Moje dane są następujące:

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 

Chcę skrypt awk, że mogę przekazać zmienną i wtedy skrypt awk zrobić regex do zmiennej. Mam ten skrypt teraz o nazwie "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"; 
} 

Wzywam skrypt tak:

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

Zwraca następujące, co jest dobrym rozwiązaniem.

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

Ale teraz chcę poszukać pewnego przedrostka "Mc". Mógłbym to zakodować, ale chcę, aby skrypt awk był elastyczny. Napisałem następujące w 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"; 
} 

Wzywam skrypt tak:

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

Ale teraz nie znajdzie żadnych rekordów.

Problem stanowi wzorzec wyszukiwania "/^prefix /". Wiem, że mogę zastąpić ten wzorzec wyszukiwania przez inny niż regex, tak jak w pierwszym skrypcie, ale przypuśćmy, że chcę to zrobić za pomocą wyrażenia regularnego, ponieważ potrzebuję, aby prefiks rzeczywiście znajdował się na początku pola lastName, ponieważ powinno być, być prefiksem i wszystkim ;-)

Jak to zrobić?

+2

porządki w przejściu 5: pozbyć się wszystkich null sprawozdania (krocząca średników), zmiana printf „\ n "aby po prostu wydrukować" ", i zmienić printf 1 $" "2 $ itd., aby po prostu wydrukować 1 $, 2 $ itd. –

Odpowiedz

16

można spróbować tego

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

wyświetlamy

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

Spójrz na awk documentation więcej. (I czytać ją od początku do końca!)

+0

Dzięki, niedługo to przetestuję. –

+4

Nic z tego podziału nie jest konieczne, ponieważ użycie name = Jane w liście arg tworzy zmienną o nazwie "name" z wartością "Jane", więc mogłeś powiedzieć "pat ="^"name' w FNR == 1 Sekcja. Ustawienie zmiennych za pomocą "-v" jest mimo wszystko preferowane, więc nie musisz zajmować się zmiennymi, które nie są wypełniane w sekcji BEGIN. –

0

Czy awk jest wymagany? Jestem pewien, że jest to całkiem możliwe w awk, ale nie wiem, czy po prostu trzeba wykonać pracę, to możesz spróbować. nie jestem jednak pewien, co to jest za ogranicznik.

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

awk jest narzędziem, które wykonuje pracę cięcia i grep w połączeniu. więc tak, możliwe z awk. Zobacz http://www.gnu.org/manual/gawk/html_node/Computed-Regexps.html#Computed-Regexps – ghostdog74

+0

Jestem zainteresowany rozwiązaniem awk. Ale dzięki. –

1

Powinieneś być w stanie korzystać z oryginalnego skryptu bez zmian - $2 ~ name już robi wyszukiwania regex więc jeśli zadzwonisz skrypt z name=^Mc to powróci imiona zaczynające się na „Mc” . W rzeczywistości nie jest to dobry przykład, ponieważ Mc pojawia się tylko na początku nazwy - jeśli użyjesz name=^Smith, to odnajdziesz Smithów, ale nie McSmithów.

+0

Ale wtedy musiałbym przekazać wyrażenie regularne (^ Smith) jako parametr i osobiście uważam, że to trochę brzydkie. –

5

Zmiana skryptu:

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

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

i nazywają go jako

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

Piękne! Sztuczka '$ 0 ~"^"' jest tym, czego szukałem. – fedorqui

Powiązane problemy