检测大文本文件中的奇怪字符

检测大文本文件中的奇怪字符

我需要检查我的整个文件是否只包含 4 个字符; “A”、“T”、“G”和“C”。我曾经使用 sed 分割字符,然后使用 grep -o 和 -v 排除目标字符进行检查。

在linux下有没有简单直接的方法来做到这一点?使用 sed/awk/grep?

(似乎有关于此相关问题的建议,但他们在命令中包含了整个文本。我的文件大小对于这个来说太大了。)

例如,输入文件中有四行,该行中可能存在其他字符(ATGC 除外)。如果可能的话,我想检测奇数字符并显示奇数字符及其所在的行数。

输入:

ATTGTAAGGTAAGTGGATTYTCCGGGRETC
TTVGGATCGTTGACCAGTK
GCCCGGGCCGGTCCTTTGGTGCGTGGGG
CTCTCCCAACCCCCCCACCCTCGACCTGAGCTCAGGCXC

期望的输出:

1:Y
1:R
1:E
2:V
2:K
4:X

答案1

-n在输出的每一行前面添加从 1 开始的行号。
-o仅打印匹配的部分。
[^ATGC] 排除字符。

grep -no '[^ATGC]' file

答案2

如果您有很多文件,并且其中大部分都是有效的,那么有一种有效的方法可以进行初步检查。只需计算无效字符:如果没有,则没有必要对文件进行更精确的测试。我们用来tr删除有效的,并wc -c计算其他的。

对于计数非零的情况,需要更精确的报告。

我建议使用 awk,并将 FS(字段分隔符)定义为“FS=[^ATGC]+”,这意味着“任何不是 A、T、G 或 C 的字符序列”。如果一行中没有错误字符,则只有一个字段。

如果存在多个字段,我们可以使用 split() 的 GNU/awk 扩展,它提供每个字段分隔符的确切文本。

#! /bin/bash

Awk='
BEGIN { FS = "[^ATGC]+"; }

function Show (tx, Local, f, c, fTxt, fSep) {
    split (tx, fTxt, FS, fSep)
    for (f = 1; f in fSep; ++f) {
        c += length (fTxt[f]);
        printf ("File %s Line %d Column %d Has :%s:\n",
            FILENAME, FNR, 1 + c, fSep[f]);
        c += length (fSep[f]);
    }
}
NF > 1 { Show( $0); }
'
    for fn in q??; do
        cc="$( tr -d 'ATGC\n' < "${fn}" | wc -c )"
        (( cc == 0 )) && { echo "$fn is OK"; continue; }
        awk "${Awk}" "${fn}"
    done

并测试:

Paul--) head q??
==> q01 <==
TTGTAAGGTAAGTGGATTYTCCGGGRETC
TTVGGATCGTTGACCAGTK
GCCCGGGCCGGTCCTTTGGTGCGTGGGG
CTCTCCCAACCCCCCCACCCTCGACCTGAGCTCAGGCXC
BAACCCCZ

==> q02 <==
GCCCGGGCCGGTCCTTTGGTGCGTGGGG

==> q03 <==
TTGTAAGGTAAGTGGATTYTCCGGGRETC
Paul--) 
Paul--) ./qFix q01 q02 q03
File q01 Line 1 Column 19 Has :Y:
File q01 Line 1 Column 26 Has :RE:
File q01 Line 2 Column 3 Has :V:
File q01 Line 2 Column 19 Has :K:
File q01 Line 4 Column 38 Has :X:
File q01 Line 5 Column 1 Has :B:
File q01 Line 5 Column 8 Has :Z:
q02 is OK
File q03 Line 1 Column 19 Has :Y:
File q03 Line 1 Column 26 Has :RE:
Paul--) 

相关内容