所以一周前我问了一个问题,> 这里 ,问题是关于排序的。如果我使用此代码来排序和创建文件:
tail -n +2 File1.txt |
split -l1 --filter='
{
head -n 1 File2.txt &&
cat <(tail -n +2 File2.txt) - |
sort -n -r -k4
; } > "$FILE"'
它确实适用于我在该示例中使用的文件,但是当我在较大的真实文件上使用它时,排序似乎不起作用。
我之前使用 LC_ALL=C 解决了这个问题,但似乎只工作了1次,所以我不知道真正的问题是什么。如果我专门打印并排序该列,它可以工作,但不能在这段代码中使用。
也许是因为一次要做的事情太多了?我有 151 列,其中注释了不同的数据,我只想对第 43 列和 151 列进行排序,但我仍然需要新的排序文件。请帮帮我。
答案1
是的,为此,我将采用前面数据示例的格式,因为列是按位置定义的,即从行开头起有多少个字符。不幸的是,正如您所发现的,如果这些列中的任何一个为空,您一直尝试使用的工具根本不会将它们计为一列:
col 1 col 2 col 3 col 4 col 5
chr3 31663820 31663820 0.713 3
col 1 col 2 col 3 col 4
chr3 33093371 3.753 4
我刚刚用 python 编写了一个快速脚本,因为它感觉更容易理解。当在命令行上给出两个文件时,它会根据该行的硬编码部分对它们进行排序,但这显然可以更改。目前,它还会针对您输入的每个字段对列表进行一次排序。但同样可以更新排序函数以按所需顺序返回浮点数元组,而不是用于比较的单个浮点数。
#! /usr/bin/python
# own_sort.py
# ./own_sort.py 'unique values file' 'duplicate values file'
# allows access to command line arguments.
import sys
# this is just to get some example inputs
test_line = 'chr3 39597927 39597927 8.721 5'
phylop_col = (test_line.find('8.721'), test_line.find('8.721')+7)
# this will return a sorting function with the particular column start and end
# positions desired, so its easy to change
def return_sorting_func(col_start, col_end):
# a sorting key for pythons built in sort. the key must take a single element,
# and return something for the sort function to compare.
def sorting_func(line):
# use the exact location, ie how many characters from the start of the line.
field = line[phylop_col[0]: phylop_col[1]]
try:
# if this field has a float, return it
return float(field)
except ValueError:
# else return a default
return float('-inf') # will give default of lowest rank
# return 0.0 # default value of 0
return sorting_func
if __name__ == '__main__':
uniq_list = []
dups_list = []
# read both files into their own lists
with open(sys.argv[1]) as uniqs, open(sys.argv[2]) as dups:
uniq_list = list(uniqs.readlines())
dups_list = list(dups.readlines())
# and sort, using our key function from above, with relevant start and end positions
# and reverse the resulting list.
combined_list = sorted(uniq_list[1:] + dups_list[1:],
key=return_sorting_func(phylop_col[0], phylop_col[1]),
reverse=True)
# to print out, cut off end of line (newline) and print header and footer around other
# results, which can then be piped from stdout.
print(dups_list[0][:-1])
for line in combined_list:
print(line[:-1])
print(dups_list[0][:-1])
因此,使用另一个问题中给定的文件,我最终得到:
~$>cat unique_data.txt
chromosoom start end phylop GPS
chr1 28745756 28745756 7.905 5
chr1 31227215 31227215 10.263 5
chr1 47562402 47562402 2.322 4
chr1 64859630 64859630 1.714 3
chr1 70805699 70805699 1.913 2
chr1 89760653 89760653 -0.1 0
chr1 95630169 95630169 -1.651 -1
~$>cat dups_data.txt
chromosoom start end phylop GPS
chr3 15540407 15540407 -1.391 -1
chr3 30648039 30648039 2.214 3
chr3 31663820 31663820 0.713 3
chr3 33093371 33093371 3.753 4
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 39597927 39597927 8.721 5
~$>cat dups_data_with_gaps_1.txt
chromosoom start end phylop GPS
chr3 15540407 15540407 -1.391 -1
chr3 30648039 30648039 2.214 3
chr3 31663820 31663820 0.713 3
chr3 33093371 3.753 4
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 39597927 8.721 5
两者给出相同的输出
~$>./own_sort.py unique_data.txt dups_data_with_gaps_1.txt
chromosoom start end phylop GPS
chr1 31227215 31227215 10.263 5
chr3 39597927 39597927 8.721 5
chr1 28745756 28745756 7.905 5
chr3 33093371 33093371 3.753 4
chr1 47562402 47562402 2.322 4
chr3 30648039 30648039 2.214 3
chr1 70805699 70805699 1.913 2
chr1 64859630 64859630 1.714 3
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 31663820 31663820 0.713 3
chr1 89760653 89760653 -0.1 0
chr3 15540407 15540407 -1.391 -1
chr1 95630169 95630169 -1.651 -1
chromosoom start end phylop GPS
但如果排序列有如下所示的空白,则该元素最终将成为最后一行:
~$>cat dups_data_with_gaps_2.txt
chromosoom start end phylop GPS
chr3 15540407 15540407 -1.391 -1
chr3 30648039 30648039 3
chr3 31663820 31663820 0.713 3
chr3 33093371 33093371 3.753 4
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 39597927 39597927 8.721 5
~$>./own_sort.py unique_data.txt dups_data_with_gaps_2.txt
chromosoom start end phylop GPS
chr1 31227215 31227215 10.263 5
chr3 39597927 39597927 8.721 5
chr1 28745756 28745756 7.905 5
chr3 33093371 33093371 3.753 4
chr1 47562402 47562402 2.322 4
chr1 70805699 70805699 1.913 2
chr1 64859630 64859630 1.714 3
chr3 37050398 37050398 1.650 2
chr3 38053456 38053456 1.1 1
chr3 31663820 31663820 0.713 3
chr1 89760653 89760653 -0.1 0
chr3 15540407 15540407 -1.391 -1
chr1 95630169 95630169 -1.651 -1
chr3 30648039 30648039 3
chromosoom start end phylop GPS
在此输出的基础上,您还可以通过管道列出“唯一”文件中的那些行在总体列表中的最终位置。
~$>./own_sort.py unique_data.txt dups_data.txt | head -n -1 | tail -n +2 | grep -Fn -f unique_data.txt
1:chr1 31227215 31227215 10.263 5
3:chr1 28745756 28745756 7.905 5
5:chr1 47562402 47562402 2.322 4
7:chr1 70805699 70805699 1.913 2
8:chr1 64859630 64859630 1.714 3
12:chr1 89760653 89760653 -0.1 0
14:chr1 95630169 95630169 -1.651 -1
grep 将对字符串进行排序 ( -F
),并输出行号 ( -n
) 并从文件中读取要搜索的字符串 ( -f unique_data.txt
)
抱歉,那里有很多例子。如果您有很多字段,您需要做的一件尴尬的事情是确保您有一种可靠的方法来识别字段的开始和结束,并为您的较大文件获取它。