Awk RegEx возвращает нада?
Итак, у меня есть этот текст в файле с именем 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';
и я пытаюсь заставить awk вернуть только номер версии из строки:
$OC_VersionString = '20.0.1';
используя (пока) эту команду:
awk -e '$1 ~ /[:digit:]+[:punct:][:digit:]+[:punct:][:digit:]+/ {print $0}' version.php
Но когда я его использую, ничего не возвращается?
Это мой первый раз , используя AWK, ооочень ... BRE чувствует "AWK-warrrd" nerk nerk nerk
Кто-нибудь может разобраться в этом?
Ответы
Не могли бы вы попробовать следующее. Написано и протестировано на показанных образцах в GNU awk.
awk '/^\$OC_VersionString/ && match($0,/\047[0-9]+\.[0-9]+\.[0-9]+\047/){
print substr($0,RSTART+1,RLENGTH-2)
}' Input_file
Более общее решение: добавление еще одного общего решения, протестированного в GNU, awkкоторое будет фиксировать номер версии в случае, если у него есть более младшая версия, например -> 20.2.0.1(в качестве примера).
awk '
/^\$OC_VersionString/ && match($0,/\047([0-9]+\.){1,}[0-9]+\047/){ print substr($0,RSTART+1,RLENGTH-2)
}' Input_file
Краткое объяснение: проверка условия/^\$OC_VersionString/для проверки того, начинается ли строка, а/$OC_VersionString/затем проверкаmatchналичиярегулярного выражения вфункцииawk. match- это функция по умолчанию, вawkкоторой мы предоставляем регулярное выражение для сопоставления, и как только мы сопоставили регулярное выражение, она устанавливает значенияRSTARTиRLENGTHпеременные по умолчанию. ГдеRSTARTнаходится начальная индексная точка согласованного регулярного выражения ИRLENGTH- длина согласованного регулярного выражения. Затем вывести подстроку из текущей строки, начальная точка которой находитсяRSTARTдо значенияRLENGTH.
Вы не можете использовать простые классы символов POSIX, вы должны заключить их в скобки, например [:digit:]=> [[:digit:]]и т. Д.
Затем вы увидите, что нужное значение находится в поле 3, пока вы используете его $1для поиска совпадения. И, наконец, вы не извлекаете поле, вы распечатываете всю запись с помощью {print $0}. Кроме того, он все равно будет содержать, 'и ';если вы его не используете gsub.
Если вы хотите исправить свой подход, вы можете использовать
s="\$OC_VersionString = '20.0.1';" awk '$3 ~ /[[:digit:]]+[[:punct:]][[:digit:]]+[[:punct:]][[:digit:]]+/{gsub(/['"'"';]/,"", $3);print $3}' <<< "$s"
# => 20.0.1
Смотрите онлайн- awkдемонстрацию .
Однако здесь sedрешение выглядит проще :
sed -n "s/.*'\\(.*\\)'.*/\\1/p" <<< "$s"
sed -n "s/.*'\\([0-9.]*\\)'.*/\\1/p" <<< "$s"
Вы можете подумать об этом awk:
awk -F '[[:blank:]]*=[[:blank:]]*' '$1 == "$OC_VersionString" {
gsub(/[^.0-9]+/, "", $2) print $2
}' file.php
20.0.1