Linux
檢測大文本文件中的奇數字元
我需要檢查我的整個文件是否只包含 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
-n使用從 1 開始的行號為每行輸出添加前綴。
-o只列印匹配的部分。
$$ ^ATGC $$排除字元。
grep -no '[^ATGC]' file
如果您有很多文件,並且其中大部分都是有效的,那麼有一種有效的方法可以進行初步檢查。只計算無效字元:如果沒有,就沒有必要對文件進行更精確的測試。我們
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--)