【问题标题】:How to print 10 letters preceding every occurrence of a particular character?如何在每次出现特定字符之前打印 10 个字母?
【发布时间】:2013-07-20 08:34:23
【问题描述】:

使用grep,我可以打印文档中所有出现的大写字母“Z”。但是,输出将显示在文档中找到每个“Z”的整行。我需要将此限制为仅打印每次出现“Z”之前出现的 10 个字母。

例如,如果文档有一行“AAAABBBBBBBBBCCCCCCDDDDDDDZ”,它将打印“CCDDDDDDD”,即前面出现的10个字母。

  • 如果“Z”之前的字母少于 10 个,则无需打印任何内容。
  • 如果“Z”在一行中出现多次,则应打印每个“Z”前面的 10 个字母,例如:“AAAABBBBBBBBBZCCCCCDDDDDDDZ”将打印“ABBBBBBBBB”和“CCDDDDDDDZ”。

结果将是这些字母的输出列表,例如:

ABBBBBBBBB
CCDDDDDDDZ

如何打印文档中每次出现字母“Z”之前的 10 个字母?

【问题讨论】:

  • 你想从AAAABBBBBBBBBZDDDDDDDZ得到什么?

标签: perl bash grep


【解决方案1】:

简单:

grep -oP '.{10}(?=Z)' <<< AAAABBBBBBBBBZCCCCCDDDDDDDZ

解释:

-o     : Print only match, not entire line
-P     : Use PCRE / Perl regex
.{10}  : Match is any 10 characters,
(?=z)  : which are followed by "Z". (Search for positive look-ahead for more details)
<<< ...: Here string

编辑:

注意:如果我们想要的 10 个字符重叠,这不起作用。例如输入=AAAABBBBBBBBBZDDDDDDDZ。如果输入包含此类模式,请参阅igegami's answer

【讨论】:

  • 不清楚这是否是要求恕我直言。如果是这样,我想您答案中的正则表达式也应该与 grep -oP 一起使用。
  • 不,如果与grep -oP 一起使用,我的模式只会打印Z(如果它完全有效的话)。
  • Nit:您的意思是不清楚 OP 是否正确说明了要求。毫无疑问,“如果“Z”在一行中多次出现,则应打印每个“Z”前面的 10 个字母”是一个要求,并且您的代码不会”不要总是遇到它。
  • 嗯.. 我同意。在这种极端情况下它确实失败了。
【解决方案2】:
$ perl -nE'say for /(?<=(.{10}))Z/g' <<'__EOI__'
AAAABBBBBBBBBZCCCCCDDDDDDDZ
AAAABBBBBBBBBZDDDDDDDZ
__EOI__
ABBBBBBBBB
CCCDDDDDDD
ABBBBBBBBB
BBZDDDDDDD

$ perl -nE'say for /(?=(.{10})Z)/g' <<'__EOI__'
AAAABBBBBBBBBZCCCCCDDDDDDDZ
AAAABBBBBBBBBZDDDDDDDZ
__EOI__
ABBBBBBBBB
CCCDDDDDDD
ABBBBBBBBB
BBZDDDDDDD

【讨论】:

  • +1。我是使用 perl 的新手。你能解释一下代码吗?我很惊讶.{10} 处于前瞻/后视状态。
  • 我现在只有一秒钟,所以我可以快速解释一下原因:如果你想要重叠匹配,那么匹配不能消耗字符,所以匹配必须是前瞻/后瞻.
猜你喜欢
  • 1970-01-01
  • 2017-02-05
  • 1970-01-01
  • 1970-01-01
  • 2020-09-07
  • 2020-03-29
  • 1970-01-01
  • 2021-09-11
  • 2017-05-21
相关资源
最近更新 更多