按第一行数字排序
sorting numerically by first row
我在 excel 中有一个包含近 900 行的文件,我将其保存为制表符分隔的 .txt 文件。我想按第一列中给出的数字对文本文件进行排序(它们的范围在 0 到 2250 之间)。其他列都是数字和不同长度的字母,例如。
myfile.txt:
0251 abcd 1234,24 bcde
2240 efgh 2345,98 ikgpppm
0001 lkjsi 879,09 ikol
我试过了
sort -k1 -n myfile.txt > myfile_num.txt
但我只是得到了一个相同的文件,但使用了新名称。我想得到:
myfile_num.txt
0001 lkjsi 879,09 ikol
0251 abcd 1234,24 bcde
2240 efgh 2345,98 ikgpppm
我做错了什么?我猜这很简单,但我会很感激我能得到的任何帮助!我只知道一点 bash 脚本,所以如果脚本是一个我能理解的非常简单的单行代码,那就太好了:)
谢谢:)
使用它来将旧的 Mac OS 回车符 return 转换为换行符:
tr '\r' '\n' < myfile.txt | sort
如前所述here you can have problems with this (and in the other pseudo-follow-up-duplicate question你问了,是的,你问了)
tr '\r' '\n' < myfile.txt | sort -n
它在 MSYS 上运行良好,但在某些平台上您可能需要添加:
export LC_CTYPE=C
或 tr
会将文件视为文本文件,并且可能会在达到最大行数限制后将其标记为已损坏。
显然我无法对其进行测试,但我相信它会根据我在链接答案中阅读的内容解决问题。
一种python方法(python 2 & 3兼容),不受所有shell问题的影响。效果很好,而且便携。我注意到输入文件有一些“0x8C”字符(奇异点),可能会混淆 tr
命令。
下面妥善处理:
import csv,sys
# read the file as binary, as it is not really text
with open("Proteins.txt","rb") as f:
data = bytearray(f.read())
# replace 0x8c char by classical dots
for i,c in enumerate(data):
if c>0x7F: # non-ascii: replace by dot
data[i] = ord(".")
# convert to list of ASCII strings (split using the old MAC separator)
lines = "".join(map(chr,data)).split("\r")
# treat our lines as input for CSV reader
cr = csv.reader(lines,delimiter='\t',quotechar='"')
# read all the lines in a list
rows = list(cr)
# perform the sort (tricky)
# on first row, numerical, removing the leading 0 which is illegal
# in python 3, and if not numerical, put it at the top
rows = sorted(rows,key=lambda x : x[0].isdigit() and int(x[0].strip("0")))
# write back the file as a nice, legal, ASCII tsv file
if sys.version_info < (3,):
f = open("Proteins_sorted_2.txt","wb")
else:
f = open("Proteins_sorted_2.txt","w",newline='')
cw = csv.writer(f,delimiter='\t',quotechar='"')
cw.writerows(rows)
f.close()
我在 excel 中有一个包含近 900 行的文件,我将其保存为制表符分隔的 .txt 文件。我想按第一列中给出的数字对文本文件进行排序(它们的范围在 0 到 2250 之间)。其他列都是数字和不同长度的字母,例如。
myfile.txt:
0251 abcd 1234,24 bcde
2240 efgh 2345,98 ikgpppm
0001 lkjsi 879,09 ikol
我试过了
sort -k1 -n myfile.txt > myfile_num.txt
但我只是得到了一个相同的文件,但使用了新名称。我想得到:
myfile_num.txt
0001 lkjsi 879,09 ikol
0251 abcd 1234,24 bcde
2240 efgh 2345,98 ikgpppm
我做错了什么?我猜这很简单,但我会很感激我能得到的任何帮助!我只知道一点 bash 脚本,所以如果脚本是一个我能理解的非常简单的单行代码,那就太好了:)
谢谢:)
使用它来将旧的 Mac OS 回车符 return 转换为换行符:
tr '\r' '\n' < myfile.txt | sort
如前所述here you can have problems with this (and in the other pseudo-follow-up-duplicate question你问了,是的,你问了)
tr '\r' '\n' < myfile.txt | sort -n
它在 MSYS 上运行良好,但在某些平台上您可能需要添加:
export LC_CTYPE=C
或 tr
会将文件视为文本文件,并且可能会在达到最大行数限制后将其标记为已损坏。
显然我无法对其进行测试,但我相信它会根据我在链接答案中阅读的内容解决问题。
一种python方法(python 2 & 3兼容),不受所有shell问题的影响。效果很好,而且便携。我注意到输入文件有一些“0x8C”字符(奇异点),可能会混淆 tr
命令。
下面妥善处理:
import csv,sys
# read the file as binary, as it is not really text
with open("Proteins.txt","rb") as f:
data = bytearray(f.read())
# replace 0x8c char by classical dots
for i,c in enumerate(data):
if c>0x7F: # non-ascii: replace by dot
data[i] = ord(".")
# convert to list of ASCII strings (split using the old MAC separator)
lines = "".join(map(chr,data)).split("\r")
# treat our lines as input for CSV reader
cr = csv.reader(lines,delimiter='\t',quotechar='"')
# read all the lines in a list
rows = list(cr)
# perform the sort (tricky)
# on first row, numerical, removing the leading 0 which is illegal
# in python 3, and if not numerical, put it at the top
rows = sorted(rows,key=lambda x : x[0].isdigit() and int(x[0].strip("0")))
# write back the file as a nice, legal, ASCII tsv file
if sys.version_info < (3,):
f = open("Proteins_sorted_2.txt","wb")
else:
f = open("Proteins_sorted_2.txt","w",newline='')
cw = csv.writer(f,delimiter='\t',quotechar='"')
cw.writerows(rows)
f.close()