我有一個資料儲存在三列中,如下所示:
3651 3631 3913
3667 3996 4276
3674 4486 4605
3707 4706 5095
3720 5174 5326
3750 5439 5899
3755 5928 6263
3767 6437 7069
3779 7157 7232
3882 7384 7450
3886 7564 7649
3900 7762 7835
4006 7942 7987
4015 8236 8325
4026 8417 8464
4065 8571 8737
4156 6790 7069
4493 7157 7450
4541 7564 7649
4551 7762 7835
4597 7942 7987
4756 8236 8325
4776 8417 8464
其中第一列是特定值,第二列是開始,第三列是結束。第一列有 825849 行,第二列和第三列有 58386 行。如果值位於開始和結束之間,我需要從第一個開始計數。
我知道在我的文件中,第 1 列中的前 12 個特定值位於第一個開始和結束之間,接下來的 5 個特定值位於第二個開始和結束之間,依此類推。我需要檢查整個文件。我已經嘗試過這個,它可以工作,但速度非常慢:
coords='final_exons.txt'
snp=( $( cat $coords | awk '{print $1}') )
exon_start=( $( cat $coords | awk '{print $2}') )
exon_end=( $( cat $coords | awk '{print $3}') )
i=0
counter=0
for value in ${exon_end[@]}; do
new_val=$counter
counter=0
let "i++"
for snps in ${snp[@]}; do
if [[ $value > $snps ]]; then
#statements
let "counter++"
#$counter=$(echo "scale=2; $counter-$new_val" | bc)
else
#$new_val=$(echo "scale=2; $counter-$")
break
fi
done
#echo "NOWENOWE $new_val "
#echo "COUNTER $value : $counter "
final=$(echo "scale=2; sqrt(($counter-$new_val)^2)" | bc)
echo "Exon $i : $final SNPs"
done
預先感謝您提供任何提示和技巧
答案1
- 將每個值放在一行中,但透過附加
S
或標記「開始」和「結束」E
。現在對值進行數字排序。你會得到類似的東西
3631S
3651
3667
...
3900
3913E
3996S
4006
...
- 計算 a
S
和E
終止值之間出現的次數。
寫好劇本,開心就好!
awk '
{print $1}
$3!="" {print $2"S"; print $3"E"}
' final_exons.txt | sort -n | awk '
!/E|S/ {count++; next}
/S/ {count=0; next}
/E/ {print line++": "count}'
第一個執行awk
步驟sort
1 $3!=""
。$2!=""
第二個對應awk
於步驟 2 S
。E
在您提供的範例文件上運行時的輸出是0: 12; 1: 5; 2: 4; 3: 2; ...; 22: 0
.
答案2
我可以使用 awk:
awk '{if( ($1 > $2) && ($1 < $3) ){print NR" "$1" "$2" "$3}}' final_exons.txt
但如果 col1 和( col2 和 col3 )是分開處理的,你最好將它們分成單獨的檔案。或者把資料存入資料庫,然後在裡面做區間測試。但最有效的方法可能是將資料載入到常規數組中,並用其他腳本語言(php、python、perl ...)實現測試循環