我有一个文本文件,其中包含一些航空公司账号:
Pesanan anda telah dikirim oleh jasa pengiriman NinjaVanID dengan nomor resi NLIDRT0000399000
Paket telah dikirim melalui TIKI. no.resi 885000210000. Cek status pesanan di https://example.com/resi/
Pesanan telah dikirim melalui JNE. no.resi JNRP-0000708000. Cek status H+1 di www.example.co.id or atau menghubungi 021-2927.0000
Pesanan anda telah dikirim oleh jasa pengiriman LEX ID dengan nomor resi LXRP-9295841000
我想提取这些空运提单编号:
NLIDRT0000399000
885000210000
JNRP-0000708000
LXRP-9295841000
以下是规则:
NLIDRT
JNRP-
LXRP-
始终相同,只有背后的数字不同这是我到目前为止所尝试的但不起作用:
grep -e 'NLIDRT\K(\d+)' -e 'TIKI, no\.resi \K(\d+)' -e 'JNRP-\K(\d+)' -e 'LXRP-\K(\d+)' awb.txt
我该怎么做?命令无关紧要,可以是awk / grep / sed
答案 0 :(得分:0)
示例:
grep -Eo '\<((NLIDRT|JNRP-|LXRP-)[0-9]{10}|[0-9]{12})\>' <<\eof
Pesanan anda telah dikirim oleh jasa pengiriman NinjaVanID dengan nomor resi NLIDRT0000399000
Paket telah dikirim melalui TIKI. no.resi 885000210000. Cek status pesanan di https://example.com/resi/
Pesanan telah dikirim melalui JNE. no.resi JNRP-0000708000. Cek status H+1 di www.example.co.id or atau menghubungi 021-2927.0000
Pesanan anda telah dikirim oleh jasa pengiriman LEX ID dengan nomor resi LXRP-9295841000
eof
结果:
NLIDRT0000399000
885000210000
JNRP-0000708000
LXRP-9295841000
说明:
grep -Eo '\<((NLIDRT|JNRP-|LXRP-)[0-9]{10}|[0-9]{12})\>'
\<
表示单词的开头(这样我们就不会在单词内部开始匹配;例如我们不应该匹配XJNRP-
)
有两种选择:(
带前缀或|
带前缀)
带前缀的变体为(NLIDRT|JNRP-|LXRP-)[0-9]{10}
,即(
NLIDRT
或JNRP-
或LXRP-
)
之一10位数。
不带前缀的变体是12位数。
\>
表示单词结束,因此我们不会匹配较长的数字序列或类似...89XX
的内容。
请注意grep -E
启用扩展正则表达式。
请注意,10位和12位数的规则是我的印象,可能是错误的。如果您想要一个或多个数字(而不是10和12),请说[0-9]+
。如果您想要10个或更多人说[0-9]{10,}
。
答案 1 :(得分:0)
您使用的是与PCRE兼容的模式,其中\d
matches digits和\K
是match reset operator,省略了到目前为止匹配的全文。这不是你需要的,因为前缀是预期匹配的一部分。
我建议使用
grep -oE '(TIKI\. *no\.resi *|NLIDRT|JNRP-|LXRP-)?[0-9]{10,}'
-o
选项使grep
返回匹配的子字符串,而不是匹配发生的整行。
POSIX ERE模式(由于-E
选项)匹配
(TIKI\. *no\.resi *|NLIDRT|JNRP-|LXRP-)?
- 一个可选的(1或0次)子字符串:
TIKI\. *no\.resi *
- TIKI.
,然后是0 +空格,no.resi
和0+空格(用[[:space:]]
替换空格以匹配任何空格)|
- 或NLIDRT
- NLIDRT
substring |
- 或JNRP-
- JNRP-
substring |
- 或LXRP-
- LXRP-
substring [0-9]{10,}
- 10位或更多位数。 注意:如果要将这些AWB作为整个单词进行匹配(如果没有字母,数字和_
字符“粘在一起”),您可以使用字边界:
grep -oE '\b(TIKI\. *no\.resi *|NLIDRT|JNRP-|LXRP-)?[0-9]{10,}\b'
或
grep -oE '\<(TIKI\. *no\.resi *|NLIDRT|JNRP-|LXRP-)?[0-9]{10,}\>'
其中\b
是单词/非单词char之间的字符串中的位置,或者字符串的开头和单词char之间,或单词char和字符串结尾之间的位置,\<
匹配非单词char /字符串开头和单词char(前导单词边界)之间的位置,\>
是结束单词边界(单词和非单词char /字符串结尾之间的位置。
s='Pesanan anda telah dikirim oleh jasa pengiriman NinjaVanID dengan nomor resi NLIDRT0000399000
Paket telah dikirim melalui TIKI. no.resi 885000210000. Cek status pesanan di https://www.jne.co.id/resi/
Pesanan telah dikirim melalui JNE. no.resi JNRP-0000708000. Cek status H+1 di www.jne.co.id or atau menghubungi 021-2927.8888
Pesanan anda telah dikirim oleh jasa pengiriman LEX ID dengan nomor resi LXRP-9295841000'
echo "$s" | grep -oE '(TIKI\. *no\.resi *|NLIDRT|JNRP-|LXRP-)?[0-9]{10,}'
结果:
NLIDRT0000399000
TIKI. no.resi 885000210000
JNRP-0000708000
LXRP-9295841000