Vì vậy, tôi có một dòng:
ID: 54376
Bạn có thể giúp tôi tạo một regex chỉ trả về số mà không có "ID:" không?
LƯU Ý: Chuỗi này nằm trong một tệp.
Vì vậy, tôi có một dòng:
ID: 54376
Bạn có thể giúp tôi tạo một regex chỉ trả về số mà không có "ID:" không?
LƯU Ý: Chuỗi này nằm trong một tệp.
Câu trả lời:
Thử cái này:
grep -oP '(?<=ID: )[0-9]+' file
hoặc là:
perl -nle 'print $1 if /ID:.*?(\d+)/' file
-o
và -P
là các phần mở rộng GNU tới grep
. -o
cũng hoạt động trên BSD. Hỗ trợ PCRE -P
không phải lúc nào cũng được biên dịch.
Sử dụng egrep
với -o
hoặc grep
với -Eo
tùy chọn để chỉ nhận được phân đoạn phù hợp. Sử dụng [0-9]
như regex để chỉ lấy số:
grep -Eo [0-9]+ filename
Có nhiều cách để làm điều này. Ví dụ:
Sử dụng GNU grep
với các PCRE gần đây và khớp các số sau ID:
:
grep -oP 'ID:\s*\K\d+' file
Sử dụng awk
và chỉ cần in trường cuối cùng của tất cả các dòng bắt đầu bằngID:
awk '/^ID:/{print $NF}' file
Tuy nhiên, điều đó cũng sẽ in các trường không phải là số, để chỉ lấy số và chỉ trong trường thứ hai, hãy sử dụng
awk '($1=="ID:" && $2~/^[0-9]+$/){print $2}' file
Sử dụng GNU grep với Biểu thức chính quy mở rộng và phân tích cú pháp hai lần:
grep -Eo '^ID: *[0-9]+' file | grep -o '[0-9]*'
\K
đang làm trong ví dụ đầu tiên?
-o
để chỉ in phần phù hợp nhưng cũng loại bỏ những thứ tôi không quan tâm. So sánh echo "foobar" | grep -oP "foobar"
vàecho "foobar" | grep -oP 'foo\Kbar'
sed -n '/ID: 54376/,${s/[^ 0-9]*//g;/./p}'
Điều đó sẽ chỉ in tất cả các số và không gian xảy ra sau ID: 54376
trong bất kỳ đầu vào tập tin.
Tôi vừa cập nhật ở trên một chút để làm cho nó nhanh hơn một chút *
và không p
xóa các dòng trống sau khi xóa các ký tự không phải là {số, dấu cách}.
Nó giải quyết các dòng từ regex /ID: 54376/
,
đến $
cuối cùng và trên chúng s///
loại bỏ tất cả hoặc bất kỳ *
ký tự nào sau đó ^
không đưa ra bất kỳ dòng nào có ký tự còn lại.[^ 0-9]*
p
/
/
.
{
echo line
printf 'ID: 54376\nno_nums_or_spaces\n'
printf '%s @nd 0th3r char@cter$ %s\n' $(seq 10)
echo 'ID: 54376'
} | sed -n '/ID 54376/,${s/[^ 0-9]*//g;/./p}'
54376
1 03 2
3 03 4
5 03 6
7 03 8
9 03 10
54376
Sử dụng sed:
{
echo "ID: 1"
echo "Line doesn't start with ID: "
echo "ID: Non-numbers"
echo "ID: 4"
} | sed -n '/^ID: [0-9][0-9]*$/s/ID: //p'
Là -n
"không in bất cứ thứ gì theo mặc định", /^ID: [0-9][0-9]*$/
là "cho các dòng khớp với biểu thức chính quy này" (bắt đầu bằng "ID:", sau đó 1 hoặc nhiều chữ số, sau đó là cuối dòng) và s/ID: //p
có dạng s/pattern/repl/flags
- s
có nghĩa là chúng tôi đang thực hiện thay thế, để thay thế mẫu "ID: "
bằng văn bản thay thế ""
(chuỗi trống) bằng cách sử dụng p
cờ, có nghĩa là "in dòng này sau khi thực hiện thay thế".
Đầu ra:
1
4
Một lệnh GNU sed khác,
sed -nr '/ID: [0-9]+/ s/.*ID: +([0-9]+).*/\1/p' file
Nó in bất kỳ số nào sau ID:
+
. Nếu sự khác biệt giữa một ký tự và 3 ký tự là tập lệnh của bạn có thể không hoạt động trong tất cả các sed
s thì có lẽ bạn nên làm : sed -n '/ID: \([0-9][0-9]*\).*/{s//\1/;s/.*[^0-9]//;/./p}'
. Câu trả lời của bạn cũng bỏ lỡ đầu tiên ID: [0-9]
trên một dòng chứa hai lần xuất hiện ID: [0-9]
.
Sử dụng grep + awk:
grep "^ID" your_file | awk {'print $2'}
Phần thưởng: dễ đọc :)
grep
nếu bạn đang sử dụng awk
. awk '/^ID/ { print $2 }'
thực hiện điều tương tự và tránh các vấn đề đệm dòng grep . Nó cũng khá giống với một trong những giải pháp trong câu trả lời của @ terdon.