使用 Sed/AWK/Perl 从块中提取第 K 行

发布于 2024-10-19 07:09:08 字数 596 浏览 2 评论 0原文

我有一些数据看起来像这样。它分为四行。每个块都以 @ 字符开头。

@SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
AAAAAAAAAAAAAAAAAAAAAAAAAAA
+SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
::::::::::::::::::::::::;;8
@SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
TATAACCAGAAAGTTACAAGTAAACAC
+SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
88888888888888888888888888

我想做的是提取每个块的最后一行。产量:

::::::::::::::::::::::::;;8
888888888888888888888888888

请注意,块的最后一行可能包含任何标准 ASCII 字符 包括@

有没有一种有效的单行文字可以做到这一点?

I have some data that looks like this. It comes in chunk of four lines. Each chunk starts with a @ character.

@SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
AAAAAAAAAAAAAAAAAAAAAAAAAAA
+SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
::::::::::::::::::::::::;;8
@SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
TATAACCAGAAAGTTACAAGTAAACAC
+SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
88888888888888888888888888

What I want to do is to extract last line of each chunk. Yielding:

::::::::::::::::::::::::;;8
888888888888888888888888888

Note that the last line of the chunk may contain any standard ASCII character
including @.

Is there an effective one-liner to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

娇柔作态 2024-10-26 07:09:08

以下 sed 命令将打印模式后的第三行:

sed -n '/^@/{n;n;n;p}' file.txt

The following sed command will print the 3rd line after the pattern:

sed -n '/^@/{n;n;n;p}' file.txt
森罗 2024-10-26 07:09:08

如果没有空行:

perl -ne 'print if $. % 4 == 0' file

If there are no blank lines:

perl -ne 'print if $. % 4 == 0' file
甜点 2024-10-26 07:09:08
$ awk 'BEGIN{RS="@";FS="\n"}{print $4 } ' file

::::::::::::::::::::::::;;8
88888888888888888888888888

如果你总是将这 4 行放在一个块中,那么其他一些方式

$ ruby -ne 'print if $.%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888

$ awk 'NR%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888

似乎你的行总是在以“+”开头的行之后,所以

$ awk '/^\+/{getline;print}' file
::::::::::::::::::::::::;;8
88888888888888888888888888

$ ruby -ne 'gets && print if /^\+/' file
::::::::::::::::::::::::;;8
88888888888888888888888888
$ awk 'BEGIN{RS="@";FS="\n"}{print $4 } ' file

::::::::::::::::::::::::;;8
88888888888888888888888888

If you always have those 4 lines in a chunk, some other ways

$ ruby -ne 'print if $.%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888

$ awk 'NR%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888

It also seems like your line is always after the line that start with "+", so

$ awk '/^\+/{getline;print}' file
::::::::::::::::::::::::;;8
88888888888888888888888888

$ ruby -ne 'gets && print if /^\+/' file
::::::::::::::::::::::::;;8
88888888888888888888888888
灵芸 2024-10-26 07:09:08

这会打印以 @ 开头的之前行以及最后一行。它可以处理大小不统一的块,但假设只有块前导行以 @ 开头。

sed -ne '1d;$p;/^@/!{x;d};/^@/{x;p}' file

一些解释是按顺序进行的:

  • 首先,您不需要第一行,因此删除它 1d
  • 接下来,您总是需要最后一行,因此打印它 $p
  • 如果您不需要'没有匹配项,将其交换到保留缓冲区中并删除它 x;d
  • 如果确实有匹配项,请将其从保留缓冲区中交换出来,然后打印它 x;p

This prints the lines before lines that starts with @, and also the last line. It can work with non uniform sized chunks, but assumes that only a chunk leading line starts with @.

sed -ne '1d;$p;/^@/!{x;d};/^@/{x;p}' file

Some explanation is in order:

  • First you don't need the first line so delete it 1d
  • Next you always need the last line, so print it $p
  • If you don't have a match swap it into the hold buffer and delete it x;d
  • If you do have match swap it out of the hold buffer, and print it x;p
一袭白衣梦中忆 2024-10-26 07:09:08

这与dogbane的答案类似

awk '/^@/ {mark = NR} NR == mark + 3 {print}' inputfile

,并且像那个答案一样,无论每个块中有多少行(只要至少有4行)都会起作用。

然而,与该答案的直接模拟是:

awk '/^@/ {next; next; next; print}' inputfile

This works similarly to dogbane's answer

awk '/^@/ {mark = NR} NR == mark + 3 {print}' inputfile

And, like that answer, will work regardless of the number of lines in each chunk (as long as there are at least 4).

The direct analog to that answer, however, would be:

awk '/^@/ {next; next; next; print}' inputfile
听不够的曲调 2024-10-26 07:09:08

这可以使用 grep 轻松完成

grep -A 1 '^@' ./infile

this can be done using grep easily

grep -A 1 '^@' ./infile
坏尐絯 2024-10-26 07:09:08

这可能对你有用(GNU sed):

sed '/^@/,+2d' file

This might work for you (GNU sed):

sed '/^@/,+2d' file
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文