第n次匹配后打印行


8

我希望在以下文件中显示第4598行。实际上,我想在第n次匹配后显示该行。在这种情况下,第三次出现的行<Car>。我该怎么办?

<Car>
10456
</Car>
<Car>
70192
</Car>
<Car>
4598
</Car>

1
尽管可以使用sedawk甚至是实现您想要的功能grep,但建议使用XML解析器。
devnull 2014年

XML仅用于示例,文本可以是任何格式
DJ180 2014年

Answers:


10
awk -v n=3 '/<Car>/ && !--n {getline; print; exit}'

要么:

awk '/<Car>/ && ++n == 3 {getline; print; exit}'

要将搜索模式作为变量传递:

var='<car>'
PATTERN="$var" awk -v n=3 '
  $0 ~ ENVIRON["PATTERN"] && ++n == 3 {getline; print; exit}'

在这里,使用ENVIRON而不是-vas作为-v扩展,反斜杠转义序列和反斜杠通常在正则表达式中找到(因此需要使用来加倍-v)。

GNU awk4.2或更高版本允许您将变量分配为强类型的正则表达式。只要未启用其POSIX模式(例如,通过$POSIXLY_CORRECT环境变量),您就可以执行以下操作:

# GNU awk 4.2 or above only, when not in POSIX mode
gawk -v n=3 -v pattern="@/$var/" '
  $0 ~ pattern && ++n == 3 {getline; print; exit}'

如何在上述命令中还将搜索模式也作为变量传递
WanderingMind

@WanderingMind,请参阅编辑。
斯特凡Chazelas

4

这是一个perl:

perl -ne 'print && exit if $c==3; $c++ if /<Car>/;' file 

使用GNU grep,您还可以像以下方式解析其输出:

grep -A 1 -m 3 '<Car>' file | tail -n 1

来自man grep

-A NUM, --after-context=NUM
          Print NUM lines of trailing context after matching lines.  
          Places a line containing a group separator (--) between 
          contiguous  groups  of  matches.          
-m NUM, --max-count=NUM
          Stop reading a file after NUM matching lines.  

3

有了GNU awk您就可以做到:

gawk -v RS='</Car>' 'NR==3 && $0=$2' inputFile

1

这是另一种方式sed

sed -n '/<Car>/{x;/.\{2\}/{x;$!{n;p};q};s/.*/&./;x}' infile

这是使用保留空间进行计数。
每次遇到匹配的行时,<Car>它都会x更改缓冲区并检查在保留缓冲区中是否恰好有N-1个字符出现。如果检查成功,它将x再次更改;如果不在最后一行,它将拉入下一n行并p冲洗模式空间,然后进行q设置。否则,它只会将另一个.字符添加到保留空间中,而e x会变回来。


0

这是一个简单的命令行解决方案。

grep -F -A1 '<Car>' filename | grep -E -v '<Car>|--' | tail -n +3 |head -n +1

如果在之后更改+3的值tail,则可以指定第n行。


不知道为什么要添加标签,sed,awk等。如果要使用特定应用程序,实用程序的解决方案,则应在问题或标题中指定。
bsd
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.