Dem*_*osW 6 grep text-processing bioinformatics
我有一个由文本和数字组合而成的制表符分隔文件。我想保留每一行,但我只想保留第 5 列中的六位数字(如果存在)。例如:
gene1 NM_033629 598G>A P912 syndrome 1, 192315 syndrome 2, 225750 syndrome 3 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I syndrome 1 600195 score AD rec user 234567 Source
Run Code Online (Sandbox Code Playgroud)
(以 Syndrome # 为例,这可以是任何文本,因此不是我可以搜索和删除的模式)
我希望输出是:
gene1 NM_033629 598G>A P912 192315 225750 610448 score AD hom user 123456 Source
gene2 NM_000459 613G>A V115I 600195 score AD rec user 234567 Source
Run Code Online (Sandbox Code Playgroud)
我有 4 种方法来提取 6 位数字,但是,我不能
一种。输出它起源的行中的数字
湾 使用一个编辑过的字段成功打印整行。我用来提取数字的选项是:
cat inputfile | cut -f 5 |grep -P '(? < !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -Po '(?< !\d)\d{6}(?!\d)'
cat inputfile | cut -f 5 |grep -o '[[:digit:]]*'
cat inputfile | cut -f 5 |grep -o "[0-9]\{6\}"
Run Code Online (Sandbox Code Playgroud)
我知道对列使用 cut 是不正确的,但我想确保我的提取正确,因为字段 9 中还有一个六位数字。我一直坚持把这些放在一起。在此先感谢您的任何建议
如果我理解正确的话,你希望第五列成为其中所有 6 位数字与空格的串联。
或许:
perl -F'\t' -lape '
$F[4] = join " ", grep {length == 6} ($F[4] =~ /\d+/g);
$_ = join "\t", @F' < file
Run Code Online (Sandbox Code Playgroud)
或者重复使用你对操作员的负面看法:
perl -F'\t' -lape '
$F[4] = join " ", ($F[4] =~ /(?<!\d)\d{6}(?!\d)/g);
$_ = join "\t", @F' < file
Run Code Online (Sandbox Code Playgroud)
和awk
:
awk -F'\t' -v OFS='\t' '
{
repl = sep = ""
while (match($5, /[0-9]+/)) {
if (RLENGTH == 6) {
repl = repl sep substr($5, RSTART, RLENGTH)
sep = " "
}
$5 = substr($5, RSTART+RLENGTH)
}
$5 = repl
print
}' < file
Run Code Online (Sandbox Code Playgroud)
grep
其本身并不足以完成这项任务。grep
旨在打印与模式匹配的行。一些实现如 GNU 或 ast-open grep
,或者pcregrep
可以从匹配行中提取字符串,但这非常有限。
我能想到的唯一可以在某些限制下工作的cut
++方法是实现:grep
paste
pcregrep
grep
n='(?:.*?((?1)))?'
paste <(< file cut -f1-4) <(< file cut -f5 |
pcregrep --om-separator=" " -o1 -o2 -o3 -o4 -o5 -o6 -o7 -o8 -o9 \
"((?<!\d)\d{6}(?!\d))$n$n$n$n$n$n$n$n"
) <(< file cut -f6-)
Run Code Online (Sandbox Code Playgroud)
假设每行输入至少有 6 个字段,并且每个字段的第 5 个字段有 1 到 9 个 6 位数字。