我需要检查我的整个文件是否只包含 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--)