Awk RegEx zwraca nada?
Więc mam ten tekst w pliku o nazwie version.php :
<?php
$OC_Version = array(20,0,1,1); $OC_VersionString = '20.0.1';
$OC_Edition = ''; $OC_Channel = 'stable';
$OC_VersionCanBeUpgradedFrom = array ( 'nextcloud' => array ( '19.0' => true, '20.0' => true, ), 'owncloud' => array ( ), ); $OC_Build = '2020-10-24T08:39:55+00:00 89d88b3ea5b4049355e3c49d121f82e5e62bfc44';
$vendor = 'nextcloud';
i próbuję sprawić, by awk zwrócił tylko numer wersji z wiersza:
$OC_VersionString = '20.0.1';
używając (do tej pory) tego polecenia:
awk -e '$1 ~ /[:digit:]+[:punct:][:digit:]+[:punct:][:digit:]+/ {print $0}' version.php
Ale kiedy go używam, nic nie zostaje zwrócone?
To mój pierwszy raz używam awk, sooo, ... BRE czuje się „awk-warrrd” nerk nerk nerk
Czy ktoś jest w stanie to rozwiązać?
Odpowiedzi
Czy mógłbyś spróbować śledzić. Napisane i przetestowane z pokazanymi przykładami w GNU awk.
awk '/^\$OC_VersionString/ && match($0,/\047[0-9]+\.[0-9]+\.[0-9]+\047/){
print substr($0,RSTART+1,RLENGTH-2)
}' Input_file
Bardziej ogólne rozwiązanie: Dodanie jednego bardziej ogólnego rozwiązania, przetestowanego w systemie GNU, awkktóre przechwyci numer wersji w przypadku, gdy ma bardziej pomniejszą wersję, np. -> 20.2.0.1(jako przykład).
awk '
/^\$OC_VersionString/ && match($0,/\047([0-9]+\.){1,}[0-9]+\047/){ print substr($0,RSTART+1,RLENGTH-2)
}' Input_file
Krótkie wyjaśnienie: sprawdzanie warunku w/^\$OC_VersionString/celu sprawdzenia, czy linia zaczyna się od/$OC_VersionString/tego momentu, sprawdzenie tego wyrażenia regularnego wmatchfunkcjiawk. matchjest funkcją domyślną, wawkktórej podajemy wyrażenie regularne do dopasowania, a po dopasowaniu wyrażenie regularne ustawia wartościRSTARTiRLENGTHzmienne domyślne. GdzieRSTARTjest początkowy punkt indeksu dopasowanego wyrażenia regularnego ORAZRLENGTHjest długością dopasowanego wyrażenia regularnego. Następnie wypisuje podłańcuch z bieżącego wiersza, którego punktem początkowym jestRSTARTwartość doRLENGTH.
Nie możesz używać czystych klas znaków POSIX, powinieneś je opakować wyrażeniami w nawiasach, np. [:digit:]=> [[:digit:]]Itp.
Następnie możesz zobaczyć, że żądana wartość znajduje się w polu 3, podczas $1wyszukiwania dopasowania. I wreszcie, nie wyodrębniasz pola, drukujesz cały rekord za pomocą {print $0}. Ponadto nadal będzie zawierał 'i ';jeśli nie używasz gsub.
Jeśli chcesz poprawić swoje podejście, możesz użyć
s="\$OC_VersionString = '20.0.1';" awk '$3 ~ /[[:digit:]]+[[:punct:]][[:digit:]]+[[:punct:]][[:digit:]]+/{gsub(/['"'"';]/,"", $3);print $3}' <<< "$s"
# => 20.0.1
Zobacz demo onlineawk .
Jednak sedrozwiązanie wygląda tutaj prościej :
sed -n "s/.*'\\(.*\\)'.*/\\1/p" <<< "$s"
sed -n "s/.*'\\([0-9.]*\\)'.*/\\1/p" <<< "$s"
Możesz to rozważyć awk:
awk -F '[[:blank:]]*=[[:blank:]]*' '$1 == "$OC_VersionString" {
gsub(/[^.0-9]+/, "", $2) print $2
}' file.php
20.0.1