如何从文件中提取特定字符串?

如何从文件中提取特定字符串?

我在解析数据时遇到困难。在下面所示的文件中,我想获取 后面的字符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
    

    解释

    使-ogrep 仅打印行的匹配部分并-P激活Perl 兼容正则表达式(PCRE) 语法。 in \KPCRE 会导致直到该点匹配的所有内容都被丢弃(因此不会打印,因为-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 的替换运算符。它替换fromto.第一个不替换任何内容,它会删除它们(确保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
    

    解释

    使-nperl 逐行读取其输入并应用给定的脚本-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

相关内容