Awk RegEx trả lại nada?
Vì vậy, tôi có văn bản này trong một tệp có tên 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';
và tôi đang cố yêu cầu awk chỉ trả lại số phiên bản từ dòng:
$OC_VersionString = '20.0.1';
sử dụng (cho đến nay) lệnh này:
awk -e '$1 ~ /[:digit:]+[:punct:][:digit:]+[:punct:][:digit:]+/ {print $0}' version.php
Nhưng, khi tôi sử dụng nó, không có gì được trả lại?
Đây là lần đầu tiên tôi sử dụng awk, sooo, ... BRE cảm thấy "awk-warrrd" nerk nerk nerk
Bất cứ ai có thể sắp xếp điều này?
Trả lời
Bạn có thể vui lòng thử làm theo. Được viết và thử nghiệm với các mẫu hiển thị trong GNU awk.
awk '/^\$OC_VersionString/ && match($0,/\047[0-9]+\.[0-9]+\.[0-9]+\047/){
print substr($0,RSTART+1,RLENGTH-2)
}' Input_file
Giải pháp chung chung hơn: Thêm một giải pháp chung nữa, được thử nghiệm trong GNU, giải pháp awknày sẽ ghi lại số phiên bản trong trường hợp nó có nhiều phiên bản nhỏ hơn, ví dụ -> 20.2.0.1(làm ví dụ).
awk '
/^\$OC_VersionString/ && match($0,/\047([0-9]+\.){1,}[0-9]+\047/){ print substr($0,RSTART+1,RLENGTH-2)
}' Input_file
Giải thích ngắn gọn: Kiểm tra điều kiện/^\$OC_VersionString/để kiểm tra xem một dòng có bắt đầu từ/$OC_VersionString/đó hay không sau đó kiểm tra xem regex có trongmatchchức năng của khôngawk. matchlà một hàm mặc định trongawkđó chúng tôi cung cấp regex để được so khớp và khi chúng tôi đã khớp với regex, nó sẽ đặt các giá trịRSTARTvàRLENGTHbiến mặc định. ĐâuRSTARTlà điểm bắt đầu chỉ mục của regex được so khớp VÀRLENGTHlà độ dài của regex đã so khớp. Sau đó, in chuỗi con từ dòng hiện tại có điểm bắt đầu làRSTARTgiá trịRLENGTH.
Bạn không thể sử dụng các lớp ký tự POSIX trần, bạn nên bọc chúng bằng các biểu thức dấu ngoặc, ví dụ [:digit:]=> [[:digit:]], v.v.
Sau đó, bạn có thể thấy giá trị bạn muốn nằm trong Trường 3, trong khi bạn sử dụng $1để tìm kiếm kết quả phù hợp. Và cuối cùng, bạn không trích xuất trường, bạn in toàn bộ bản ghi với {print $0}. Ngoài ra, nó sẽ vẫn chứa 'và ';nếu bạn không sử dụng gsub.
Nếu bạn muốn sửa cách tiếp cận của mình, bạn có thể sử dụng
s="\$OC_VersionString = '20.0.1';" awk '$3 ~ /[[:digit:]]+[[:punct:]][[:digit:]]+[[:punct:]][[:digit:]]+/{gsub(/['"'"';]/,"", $3);print $3}' <<< "$s"
# => 20.0.1
Xem bản demo trực tuyếnawk .
Tuy nhiên, sedgiải pháp giải pháp trông đơn giản hơn ở đây:
sed -n "s/.*'\\(.*\\)'.*/\\1/p" <<< "$s"
sed -n "s/.*'\\([0-9.]*\\)'.*/\\1/p" <<< "$s"
Bạn có thể cân nhắc điều này awk:
awk -F '[[:blank:]]*=[[:blank:]]*' '$1 == "$OC_VersionString" {
gsub(/[^.0-9]+/, "", $2) print $2
}' file.php
20.0.1