2013-03-15 19 views
15

wiem awk może zrobić podstawienie text/string z sub() i gsub() jak:Czy ktoś może mi wyjaśnić, dlaczego sub()/gsub() awk działa w ten sposób?

kent$ echo "fffff"|awk '{gsub("f", "b")}1' 
bbbbb 

lub

kent$ echo "fffff"|awk '{gsub(/f/, "b")}1' 
bbbbb 

Jednak dzisiaj zrobiłem błąd literówka, napisałem wiersz jako:

kent$ echo "fffff"|awk '{gsub('f', "b")}1' 

Ale awk nie narzekał na to, ale wygenerował wynik jak zwykle, oczywiście, nieoczekiwany wynik, zajęło mi kiedyś, aby dowiedzieć się błędu. Wyjście awk dał mi było:

bfbfbfbfbfb 

kolejny przykład:

kent$ echo "fafafafafXX"|awk '{gsub('fa', "B")}1' 
BfBaBfBaBfBaBfBaBfBXBXB 

przykład z sub() jest zbyt dziwne:

kent$ echo "thanks in advance"|awk '{sub('a', "B")}1' 
Bthanks in advance 

mógłby ktoś wytłumaczyć mi jak było dziwne podstawienie zrobić?

kent$ awk --version 
GNU Awk 4.0.2 

EDIT

dzięki za odpowiedź od Joni. Przykładem może to wyjaśnia to lepiej, po prostu dodaj go tutaj:

kent$ echo "thanks in advance"|awk '{f="k";sub('f', "B")}1' 
thanBs in advance 

kent$ echo "thanks in advance"|awk '{sub('th ank', "B")}1' 
awk: cmd. line:2: {sub(th 
awk: cmd. line:2:  ^unexpected newline or end of string 

Odpowiedz

19

Kiedy piszesz

echo "fffff"|awk '{gsub('f', "b")}1' 

co awk postrzega to {gsub(f, "b")}1. Interpretuje ona f jako zmienną, z pustą wartością i zastępuje każdy pusty łańcuch na wejściu za pomocą b.

Pusty ciąg znaków znajduje się między każdą postacią i po ostatniej, tak więc awk wstawia po b po każdym f.

można zastąpić // lub "" dla tego samego efektu, bez nieużywanej zmiennej:

echo "fffff"|awk '{gsub(//, "b")}1'   # fbfbfbfbfb 
+0

+1, brzmi rozsądnie. – Kent

+0

Myślę, że to może być sztuczka do wykorzystania, nawet jeśli jest trochę ryzykowna. :) – Kent

Powiązane problemy