我在解析数据时遇到困难。在下面所示的文件中,我想获取 后面的字符BIG**20021208*00001**
。我尝试过sed '/BIG.20021208.00001\**/!d;s///;s/\*.*//'
,但没有成功。我认为问题与行分隔符()有关…
。
BIG*20021208*00001**A1001…
TO*7284*0001…BIG*20021208*00001**A999…
NN*ST*XYZ Test Corporation*9*122334455…
NU*987 ELS.…
N4**NY*98765…
ITD*01*3*2**30**45*****60…
N3*123 Highway Street…
N4**12345…
ITD*001*3*2**30**30*****60…
BIG*20021208*00001**8263-83313…
ITD*001*3*2**30**30*****60…
BIG*20021208*00001**8263-83313…
我的预期输出是:
A1001
8263-83313
8263-83313
答案1
有很多方法可以做到这一点。例如:
grep
grep -oP 'BIG\*20021208\*00001\**\K[A-Z0-9-]+' file
解释
使
-o
grep 仅打印行的匹配部分并-P
激活Perl 兼容正则表达式(PCRE) 语法。 in\K
PCRE 会导致直到该点匹配的所有内容都被丢弃(因此不会打印,因为-o
)。[A-Z0-9-]
是一个字符类匹配从 A 到 Z 的任意大写字母、任意数字或-
且可重复一次或多次 (+
)。如果您的目标字符串也可以包含小写字母,只需使用该
-i
标志运行 grep 或将字符类更改为[a-zA-Z0-9-]
.- - 或者 - -
grep -oP 'BIG\*20021208\*00001\**\K.+(?=…)' file
解释
这就像上面的一样,只是在这里,有一个正向前瞻 (
(?=…)
) ,这意味着.+
只有在 a 之前才会匹配…
。sed
sed -rn 's/…//g;s/.*BIG\*20021208\*00001\**//p;' file
解释
是
s/from/to/
sed 的替换运算符。它替换from
为to
.第一个…
不替换任何内容,它会删除它们(确保g
对行上的所有匹配项都完成此操作)。第二个删除从行开头 (.*
) 到BIG*20021208*00001
(*
在正则表达式中具有特殊含义,因此需要使用\*
) 进行转义,然后删除 0 个或多个星号 (\**
) 的所有内容。结合起来,它们会删除除您想要的内容之外的所有内容。禁止
-n
打印任何输出。第二个替换运算符末尾p
的 导致 sed 打印替换成功的任何谎言。awk
awk -F'[*…]' '/BIG\*20021208\*00001\**/{print $(NF-1)}' file
解释
-F
将 awk 的输入字段分隔符设置为*
或…
。这意味着倒数第二个字段将是您想要的字段。上面的命令将其打印在匹配的行上BIG*20021208*00001*
。珀尔
perl -lne '/BIG\*20021208\*00001\**(.*)…/ && print "$1"' file
解释
使
-n
perl 逐行读取其输入并应用给定的脚本-e
。为每个调用添加-l
一个换行符print
。上面的命令将尝试匹配感兴趣的字符串(请参阅上面 sed 示例的说明),如果成功则打印它。您还可以使用与 awk 示例中相同的方法:
perl -F'[*…]' -lane '/BIG\*20021208\*00001\**/ && print "$F[$#F]"' file
答案2
使用awk
:
awk -F\* '/^BIG/ {gsub(/…/,""); print $NF}' file
A1001
8263-83313
8263-83313