grep (bash) 多行模式
grep (bash) multi-line pattern
在 bash (4.3.46(1)) 中,我有一些多行所谓的 fasta 记录,其中每条记录都是由在线启动的 >name 和以下几行 DNA 序列 ([AGCTNacgtn] ), 这里有3条记录:
>chr1
AGCTACTTTT
AGGGNGGTNN
>chr2
TTGNACACCC
TGGGGGAGTA
>chr3
TGACGTGGGT
TCGGGTTTTT
如何使用 bash grep 获取第二条记录?在其他语言中,人们可能会使用:
>chr2\n([AGCTNagctn]*\n)*
在 Bash 中,我尝试使用 here(以及其他 SO)中的想法。这没有用:
grep -zo '>chr2[AGCTNacgtn]+' file
结果应该是:
>chr2
TTGNACACCC
TGGGGGAGTA
解决方案
在我的系统上这是解决方案(下面几乎是 Cyrus',即没有管道到第二个 grep .
):
grep -Pzo '>chr1\n[AGCTNacgtn\n]+' file
您可以将 awk
与自定义 RS
一起使用:
awk -v n=2 -v RS='(^|\n)>' 'NR==n+1{print ">" [=10=]}' file
>chr2
TTGNACACCC
TGGGGGAGTA
使用 GNU grep:
grep -Pzo '>chr2\n[AGCTNacgtn\n]+' file | grep .
输出:
>chr2
TTGNACACCC
TGGGGGAGTA
您应该安装 FAST perl package. It contains many utilities directly usable from the shell for dealing with fasta
files, like fashead or fastail (and much more)
安装后很简单:
fashead -n2 fastafile | fastail -n1
产出
>chr2
TTGNA.....
甚至更简单
fasgrep chr2 fastafile
具有相同的输出...
试试这个 -
grep 'chr2' -A 2 file
>chr2
TTGNACACCC
TGGGGGAGTA
处理多行记录的最佳工具是awk
。
你的情况:
awk 'BEGIN{RS=">"} NR==2 {print RS[=10=]}' input.txt
input.txt
>chr1
AGCTACTTTT
AGGGNGGTNN
>chr2
TTGNACACCC
TGGGGGAGTA
>chr3
TGACGTGGGT
TCGGGTTTTT
解释:
BEGIN{RS=">"}
最初将记录分隔符设置为 ">"
NR==2
仅过滤记录 #2
{print RS[=16=]}
打印记录 #2 并返回缺失的记录分隔符
创建了 sedgrep 混合版本以通用方式支持...
您可以使用此 sedgrep shell 命令,网址为
https://github.com/iamdvr/sedgrep-shell-util
直接Link:https://github.com/iamdvr/sedgrep-shell-util/blob/main/sedgrep
对于您的情况,直接命令是...
cat <FILE_NAME> | sed -nr ':main; /^>.*chr2/ { :loop; p; n; /^>/ b main; b loop} '
sedgrep用法如下...
Default NEW_LINE_PATTERN is ^\[
Usage :
cat {INPUT_FILE_NAME} | sedgrep {NEW_LINE_PATTERN} {THREAD_OR_SEARCH_PATTERN}
cat {INPUT_FILE_NAME} | sedgrep {THREAD_OR_SEARCH_PATTERN}
sedgrep {NEW_LINE_PATTERN} {THREAD_OR_SEARCH_PATTERN} {INPUT_FILE_NAME}
sedgrep {THREAD_OR_SEARCH_PATTERN} {INPUT_FILE_NAME}
Example :
cat sampleInput.log | sedgrep 2016-05-23 DB_CONN
cat sampleInput.log | sedgrep DB_CONN
sedgrep 2016-05-23 DB_CONN sampleInput.log
sedgrep DB_CONN sampleInput.log
在 bash (4.3.46(1)) 中,我有一些多行所谓的 fasta 记录,其中每条记录都是由在线启动的 >name 和以下几行 DNA 序列 ([AGCTNacgtn] ), 这里有3条记录:
>chr1
AGCTACTTTT
AGGGNGGTNN
>chr2
TTGNACACCC
TGGGGGAGTA
>chr3
TGACGTGGGT
TCGGGTTTTT
如何使用 bash grep 获取第二条记录?在其他语言中,人们可能会使用:
>chr2\n([AGCTNagctn]*\n)*
在 Bash 中,我尝试使用 here(以及其他 SO)中的想法。这没有用:
grep -zo '>chr2[AGCTNacgtn]+' file
结果应该是:
>chr2
TTGNACACCC
TGGGGGAGTA
解决方案
在我的系统上这是解决方案(下面几乎是 Cyrus',即没有管道到第二个 grep .
):
grep -Pzo '>chr1\n[AGCTNacgtn\n]+' file
您可以将 awk
与自定义 RS
一起使用:
awk -v n=2 -v RS='(^|\n)>' 'NR==n+1{print ">" [=10=]}' file
>chr2
TTGNACACCC
TGGGGGAGTA
使用 GNU grep:
grep -Pzo '>chr2\n[AGCTNacgtn\n]+' file | grep .
输出:
>chr2 TTGNACACCC TGGGGGAGTA
您应该安装 FAST perl package. It contains many utilities directly usable from the shell for dealing with fasta
files, like fashead or fastail (and much more)
安装后很简单:
fashead -n2 fastafile | fastail -n1
产出
>chr2
TTGNA.....
甚至更简单
fasgrep chr2 fastafile
具有相同的输出...
试试这个 -
grep 'chr2' -A 2 file
>chr2
TTGNACACCC
TGGGGGAGTA
处理多行记录的最佳工具是awk
。
你的情况:
awk 'BEGIN{RS=">"} NR==2 {print RS[=10=]}' input.txt
input.txt
>chr1
AGCTACTTTT
AGGGNGGTNN
>chr2
TTGNACACCC
TGGGGGAGTA
>chr3
TGACGTGGGT
TCGGGTTTTT
解释:
BEGIN{RS=">"}
最初将记录分隔符设置为 ">"
NR==2
仅过滤记录 #2
{print RS[=16=]}
打印记录 #2 并返回缺失的记录分隔符
创建了 sedgrep 混合版本以通用方式支持... 您可以使用此 sedgrep shell 命令,网址为 https://github.com/iamdvr/sedgrep-shell-util
直接Link:https://github.com/iamdvr/sedgrep-shell-util/blob/main/sedgrep
对于您的情况,直接命令是...
cat <FILE_NAME> | sed -nr ':main; /^>.*chr2/ { :loop; p; n; /^>/ b main; b loop} '
sedgrep用法如下...
Default NEW_LINE_PATTERN is ^\[
Usage :
cat {INPUT_FILE_NAME} | sedgrep {NEW_LINE_PATTERN} {THREAD_OR_SEARCH_PATTERN}
cat {INPUT_FILE_NAME} | sedgrep {THREAD_OR_SEARCH_PATTERN}
sedgrep {NEW_LINE_PATTERN} {THREAD_OR_SEARCH_PATTERN} {INPUT_FILE_NAME}
sedgrep {THREAD_OR_SEARCH_PATTERN} {INPUT_FILE_NAME}
Example :
cat sampleInput.log | sedgrep 2016-05-23 DB_CONN
cat sampleInput.log | sedgrep DB_CONN
sedgrep 2016-05-23 DB_CONN sampleInput.log
sedgrep DB_CONN sampleInput.log