如何使用awk从文件的每一行中只提取特定的字符串?

How to extract only specific strings from each line of a file using awk?

我想知道是否有一种通用方法可以使用 awk 方法提取特定字符串,该字符串设计为 11 个字符的字母数字 字符串? 对于前

猫ext.txt

This is a sample field where the code is MGTCBEBEECL for NR
This is a sample field where the code is MGTCBEBEE01 for NR
This field must be 030 when Rule_1 = 'FR' and Rule_2  is 'EUROFRANSBI' or 'EURO_NEAR' and code is PARBFRPPXXX 
This field must be 0186 when Rule_1 = 'FR' and Rule_2  is 'EUROFRANSBI' or  'EURO_NEAR' and code is CITIFRPPXXX for the NR
For NFNC with Rule_1 is CA and Rule_2 is Universal and business code is null and official code must be 'CIBCCATTXXX'

我只想提取代码:-

MGTCBEBEECL 
MGTCBEBEE01 
PARBFRPPXXX 
CITIFRPPXXX 
CIBCCATTXXX

有将近 100 行这样的行,我希望从中提取这些不同的字符串,但我不知如何使它更通用和非冗余,因此寻求这个社区的帮助!

对于当前示例,您可以像这样使用 grep 来完成:

<ext.txt grep -oE "(code is|code must be) '?[A-Z0-9]{11}'?" | 
tr -d "'"                                                   |
grep -o '[^ ]*$'

输出:

MGTCBEBEECL
MGTCBEBEE01
PARBFRPPXXX
CITIFRPPXXX
CIBCCATTXXX

使用 gawk:

gawk -F "[ ']" 'BEGIN{ r=@/[A-Z]{11}/ }r{ for (i=1; i<=NF;i++){ if($i~r) print $i} }' ext.txt
  • -F "[ ']" 使用 space 或 ' 作为字段分隔符(也可以查找 'CIBCCATTXXX' 之类的代码)
  • r=@/[A-Z]{11}/ 分配使用的正则表达式(因为它在脚本中使用了两次
  • for(...遍历一行中的所有字段,当匹配正则表达式时打印该字段。

输出:

MGTCBEBEECL
EUROFRANSBI
PARBFRPPXXX
EUROFRANSBI
CITIFRPPXXX
CIBCCATTXXX

GNU awk 有一种使用 FPAT 的方法:

awk -v FPAT='[[:alnum:]]{11}' '{print $NF}' file
MGTCBEBEECL
MGTCBEBEE01
PARBFRPPXXX
CITIFRPPXXX
CIBCCATTXXX
  • 将 FPAT 设置为 '[[:alnum:]]{11}' GNU awk 可以处理包含十一个字符的字母数字字符串的字段。
  • {print $NF} 用于打印所需的字段。

使用任何具有 -E 的 sed 来启用 ERE,例如GNU 和 BSD seds:

$ sed -En "s/.*code (is|must be) '?([[:upper:][:digit:]]+).*//p" file
MGTCBEBEECL
MGTCBEBEE01
PARBFRPPXXX
CITIFRPPXXX
CIBCCATTXXX

我们可以使用 awkmatch 函数,在 GNU awk 中编写和测试应该在任何 awk 中工作。简单的解释是使用 awkmatch 函数,我们可以在其中使用正则表达式 [[:alnum:]]{11} 匹配每行中的 11 个连续字母数字,如果找到 TRUE 匹配,则打印匹配值的子字符串。

awk  'match([=10=],/[[:alnum:]]{11}/){print substr([=10=],RSTART,RLENGTH)}' Input_file