Linux

檢測大文本文件中的奇數字元

  • August 31, 2020

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

引用自:https://unix.stackexchange.com/questions/607020