在 Unix Shell 脚本中从文件中查找特定的字符串模式

在 Unix Shell 脚本中从文件中查找特定的字符串模式

我有以下命令。

 unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | grep  ":taxonomies-" | head -1

这给了我输出,

    <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>

但是,我只需要提取分类法-8.2.0而不是上面的完整字符串。

答案1

一种方法是使用 grep 的-o选项,并结合PCRE( -P):

   -o, --only-matching
          Print  only  the  matched  (non-empty) parts of a matching line,
          with each such part on a separate output line.
   -P, --perl-regexp
          Interpret  PATTERN  as  a  Perl  regular  expression  (PCRE, see
          below).  This is highly experimental and grep  -P  may  warn  of
          unimplemented features.

所以,你可以这样做

 unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | grep -oP ':\Ktaxonomies-[^"]*' | head -1

导致\K任何匹配到该点的内容都被忽略(因此:不会打印),并且意味着“匹配尽可能[^"]*"多的非字符”。"

其他选项包括:

  1. sed

    unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | 
        sed -n 's/.*:\(taxonomies-[^"]*\).*/\1/p' | head -1
    

    除非明确告知,否则不会打印任何内容,并且是-n替换运算符。它将用括号 ( ) 之间的部分替换该行中的所有内容。这会导致打印结果行。seds///\1p

  2. Perl

    unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | 
      perl -lne 's/.*:(taxonomies-[^"]).*/$1/ && print' | head -1
    

    与 的基本思想相同sed。如果替换成功,则打印该行。另一种选择是

    unzip -p GLP.K4C.S06F5.BG57218-rdf.zip | 
      perl -lne '/.*:(taxonomies-[^"])/ && print $1' | head -1
    

答案2

如果你知道发生:输入中的字符,您可以执行类似的操作。

echo " <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>" | 
awk -F\: '{print $4}' | sed 's/..$//'

awk命令打印后面的第四个字符串:分隔符,该sed命令用于删除最后 2 个字符以获得所需的输出。

但是,此方法是否有效取决于您的输入特登在评论中指出

编辑

sed如果我们使用建议的解决方案,则可以很好地避免最终的管道杰森·瑞安评论。因此,该命令实际上可以改写为:

 echo " <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>" | 
 awk -F: '{sub(/\/>/,""); print $4}'

仅使用 cut 和 rev 的另一种解决方案可以构建为,

echo " <j.2:Taxo_Version rdf:resource="refmat:taxonomies-8.2.0"/>" | 
cut -d ':' -f4 | rev | cut -c 3- | rev

同样,分隔符的指定取决于输入文件,并且从您提供的示例中,我需要提取的字符出现在分隔符的第四个位置之后。我用来提取第四cut分隔符之后的子字符串,并使用良好的旧技术来反转字符串并删除最后 3 个字符,然后再次应用它以获得实际的字符串。revrev

相关内容