我有那種大檔案:
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
我需要訂購第三列,但保持第一列的順序。我應該得到:
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
我做了-k1,1 -k3,3n但喜歡檔案很大,第一列看起來像:
PB.1060.1_1000_1999
PB.1060.1_1000_1999
PB.1060.1_100_1099
PB.1060.1_100_1099
PB.1060.1_100_1099
PB.1060.1_100_1099
PB.1060.1_100_1099
PB.1060.1_1001_2000
PB.1060.1_1001_2000
PB.1060.1_1002_2001 ...
它應該保持原始檔案的順序:
PB.1060.1_1_1000
PB.1060.1_1_1000
PB.1060.1_1_1000
PB.1060.1_1_1000
PB.1060.1_2_1001
PB.1060.1_2_1001
PB.1060.1_3_1002
PB.1060.1_4_1003
PB.1060.1_4_1003 ...
但沒辦法..有什么幫助嗎?
uj5u.com熱心網友回復:
嘗試sort -k1,1 -k3,3n input:
$ cat input
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
$ sort -k1,1 -k3,3n input
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
uj5u.com熱心網友回復:
假設/理解:
- 第一列已根據“版本”排序進行排序
- 我們需要保持第一列的順序,然后按第三列對重復項進行排序
在我們的示例資料中添加幾行:
$ cat input.dat
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
PB.1060.1_100_1099 Chr1 905 423 20733234
PB.1060.1_100_1099 Chr1 1020 523 20734234
PB.1060.1_1000_1999 Chr1 3422 223 20731234
PB.1060.1_1000_1999 Chr1 200 323 20732234
PB.1060.1_1001_2000 Chr1 900 623 20735234
一個sort想法:
sort -k1,1V -k3,3n input.dat
在哪里:
- 對第一列應用“版本”排序
- 將第三列排序為“數字”
這會產生:
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
PB.1060.1_100_1099 Chr1 905 423 20733234
PB.1060.1_100_1099 Chr1 1020 523 20734234
PB.1060.1_1000_1999 Chr1 200 323 20732234
PB.1060.1_1000_1999 Chr1 3422 223 20731234
PB.1060.1_1001_2000 Chr1 900 623 20735234
uj5u.com熱心網友回復:
由于您的檔案已經按其第一列排序,并且假設您沒有太多具有相同第一列值的行,我們可以將具有相同第一列值的所有行存盤在記憶體中。一旦我們遇到新的第一列值或檔案末尾,我們就會按第三列對存盤的行進行排序并列印它們。
使用 GNU awk:
$ awk -vi=1 '
function sort(a, b) {
n = asort(b, c)
for(i = 1; i <= n; i ) {
for(j = 1; j <= n; j ) {
if(b[j] == c[i]) {
print a[j]
break
}
}
}
delete a
delete b
}
NR > 1 && $1 != prev {
sort(l, v)
i = 1
}
{
v[i] = $3
l[i ] = $0
prev = $1
}
END {
sort(l, v)
}' file
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
我們首先定義帶有sort兩個引數的函式:a第一列相同的所有行b的陣列,第三列的陣列。兩個陣列都按數字索引,從 1 開始。
asort(b, c)將 array復制b到 array c,按其內容排序,從 1c重新索引c它并回傳元素的數量。兩個嵌套回圈列印按第三列排序的行。
當然,如果您有大量具有相同第一列的連續行,這可能會耗盡可用記憶體。如果是這種情況,基于將檔案拆分為具有不同第一列值的多個檔案,分別對它們進行排序并重新連接它們的解決方案可能是您的最佳選擇。
$ awk -vi=0 '
NR == 1 || $1 != prev {
i = 1
n = sprintf("x0d", i)
prev = $1
}
{
print > n
}' file
$ for f in x*; do sort -n -k3,3 -o $f.sorted $f; done
$ cat x*.sorted > file.sorted
$ rm x*
$ cat file.sorted
PB.1060.1_1_1000 Chr1 1 293 20733996
PB.1060.1_1_1000 Chr1 287 485 20733577
PB.1060.1_1_1000 Chr1 484 817 20733209
PB.1060.1_2_1001 Chr1 286 484 20733577
PB.1060.1_2_1001 Chr1 483 816 20733209
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/431389.html
