我有一個看起來像這樣的文本檔案
我想將每個 ATGC 成對加入,從第七列開始,以達到這個效果:
我嘗試在 linux 上使用 awk 命令執行此操作,但速度太慢:
enter image description here
非常感謝!
使用任何語言的代碼,希望是 python
uj5u.com熱心網友回復:
awk 解決方案
我有一個替代awk解決方案,它使用全域替換而不是回圈來格式化資料。我懷疑這會比您嘗試的更快,但沒有您的檔案可以嘗試。
這是解決方案,(替換data.txt為您的資料檔案的路徑):
awk '{$1 =$1"*"$2"*"$3"*"$4"*"$5"*"$6"*"; $2=$3=$4=$5=$6=""; print $0}' data.txt | awk 'BEGIN{FS="*"} {gsub(/ /,"",$0);gsub(/.{2}/,"& ",$7); print $0}'
解釋
此程序的第一部分將第一個欄位重寫為$1包含連接的前 6 個欄位的字串,并以插入的星號 (*) 結尾 - 選擇作為唯一字符,選擇檔案中其他位置不存在的字符。在將新版本的行列印到之前,$2將包含的欄位設定為空字串。$6$0stdout
$2在這個階段,輸出有許多不需要的空格,因為空欄位$6仍然有它們的輸出欄位分隔符(空格)。
輸出通過管道傳送到第二個 awk 程序,該程序用星號分隔欄位BEGIN{FS="*"},總共提供 7 個欄位,其中包含許多不需要的空格。
全域替換用于使用$0空字串替換記錄 ()中的所有空格gsub(/ /,"",$0)。
因為欄位由星號定義,所以現在沒有任何空格的整個序列 (GATC) 資料保存在一個欄位中,即最后一個欄位$7。
第二個全域替換用于在此序列中的每個第二個字符之后插入一個空格:gsub(/.{2}/,"& ",$7).
最后,列印整個記錄 ( print $0) 輸出資料,其中未更改的輸出欄位分隔符(空格)有效地替換了星號。
例子
我使用結構如下的檔案測驗了該程序:
(data.txt file)
one two three four five six A A C C G G C C G G
輸出:
one two three four five six AA CC GG CC GG
編輯 - 處理過多的欄位編號
OP 報告上述解決方案在他們的情況下失敗,并顯示已超過最大欄位數(~32k)的訊息。
一種解決方法是使用gawkGNU 實作awk(內置在許多 linux 發行版中或可在:https ://www.gnu.org/software/software.html 獲得),它可以處理比 awk 更多的欄位。
sed使用和的替代解決方案awk
或者,可以通過使用流編輯器插入唯一字符來預處理資料以創建較少數量的欄位sed。OP 資料中需要重新格式化的資料存在于欄位 7..n 中,其中 n 很大,可以超過 32k。通過在這些欄位的開頭放置一個唯一字符,awk可以在唯一字符處拆分每一行(記錄),從而只處理 2 個欄位。與先前解決方案所建議的方式相同,可以通過對欄位 2 應用全域替換來進行所需的更改。
由于前六個欄位之間的空格未被觸及,因此該解決方案變得比原始解決方案更簡單:
sed 's/ /*/6' data.txt | awk 'BEGIN{FS="*"} {gsub(/ /,"",$2); gsub(/.{2}/,"& ",$2); print $0}
(將 data.txt 更改為資料檔案的路徑)
解釋
sed用星號(必須是唯一的)替換每個原始行(記錄)中的第六個空格:sed 's/ /*/6'
stdout插入到awk塊將BEGIN欄位分隔符設定為星號的位置。awk 現在看到每一行有兩個欄位,一個包含(空格分隔的)第 1-6 列,另一個包含由空格分隔的 ATCG 序列流。
awk 現在可以通過將全域替換定位到欄位 2 來用空字串替換序列資料中的空格:gsub(/ /,"",$2)
gsub(/.{2}/,"& ",$2)最后,在列印輸出之前,再次處理欄位 2 以每隔一個字符插入一個空格。
警告
這種替代解決方案是否會克服欄位限制問題取決于內部awk解釋$0(整行)的方式。我的預感是它不會將其視為欄位的集合,而是將其視為單個字串。如果是這樣,并且可以處理該長度的字串,它應該可以作業。(一個資訊豐富的實驗)。如果字串長度有限制,可以修改該程序以在序列資料中插入幾個星號,比如在 1000 個塊中,每個記錄都像以前一樣處理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/525548.html
標籤:Pythonmatlab
上一篇:如何從元胞陣列生成字串
