Regex sẽ grep số sau chuỗi cụ thể


8

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:


14

Thử cái này:

grep -oP '(?<=ID: )[0-9]+' file

hoặc là:

perl -nle 'print $1 if /ID:.*?(\d+)/' file

Cảm ơn bạn đã trả lời nhưng tôi không cần tất cả các số từ một tệp chỉ cần một số xảy ra sau ID:
Blake Gibbs

Cập nhật câu trả lời của tôi.
cuonglm

1
Lưu ý rằng -o-Plà các phần mở rộng GNU tới grep. -ocũng hoạt động trên BSD. Hỗ trợ PCRE -Pkhông phải lúc nào cũng được biên dịch.
Matt

4

Sử dụng egrepvới -ohoặc grepvới -Eotù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

1
OP cần nó để khớp chỉ sau một chuỗi cụ thể. Xem tiêu đề của câu hỏi.
terdon

4

nhiều cách để làm điều này. Ví dụ:

  1. Sử dụng GNU grepvới các PCRE gần đây và khớp các số sau ID::

    grep -oP 'ID:\s*\K\d+' file
    
  2. Sử dụng awkvà 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
    
  3. 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]*'
    

Cảm ơn! Điều gì \Kđang làm trong ví dụ đầu tiên?
rnd_d

2
@rnd_d đó là cấu trúc Biểu thức chính quy tương thích Perl (PCRE) có nghĩa là "bỏ qua mọi thứ khớp với điểm này". Nó được sử dụng như một cái nhìn, nó cho phép tôi sử dụng -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"echo "foobar" | grep -oP 'foo\Kbar'
terdon

4
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: 54376trong 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 pxó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//.

BẢN GIỚI THIỆU:

{
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}'

ĐẦU RA:

 54376
1  03  2
3  03  4
5  03  6
7  03  8
9  03  10
 54376

1

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'

-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: //pcó dạng s/pattern/repl/flags- scó 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 pcờ, có nghĩa là "in dòng này sau khi thực hiện thay thế".

Đầu ra:

1
4

Nó sẽ không hoạt động nếu ID xuất hiện ở trung tâm của một dòng.
Avinash Raj

Cũng không nên, dựa trên việc tôi đọc câu hỏi. Và không cố gắng xử lý sớm trường hợp đó làm cho mã đơn giản và dễ mang theo hơn.
trời ơi

0

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:


Bạn thực sự không cần +. 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 seds 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].
mikeerv

0

Sử dụng grep + awk:

  grep "^ID" your_file | awk {'print $2'}

Phần thưởng: dễ đọc :)


1
Bạn không cần grepnế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.
cas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.