如何对 1000 行文件中的每 20 行进行排序,并仅将每个间隔中具有最高值的排序行保存到另一个文件?

如何对 1000 行文件中的每 20 行进行排序,并仅将每个间隔中具有最高值的排序行保存到另一个文件?

我有一个包含 1000 行文本的文件。我想以每 20 行间隔对第四列进行排序,并将输出打印到另一个文件。有人可以帮我用 awk 或 sed 对它们进行排序吗?

这是数据结构输入的示例

   1      1.1350  1092.42    0.0000
   2      1.4645   846.58    0.0008
   3      1.4760   840.01    0.0000
   4      1.6586   747.52    0.0006
   5      1.6651   744.60    0.0000
   6      1.7750   698.51    0.0043
   7      1.9216   645.20    0.0062
   8      2.1708   571.14    0.0000
   9      2.1839   567.71    0.0023
  10      2.2582   549.04    0.0000
  11      2.2878   541.93    1.1090
  12      2.3653   524.17    0.0000
  13      2.3712   522.88    0.0852
  14      2.3928   518.15    0.0442
  15      2.5468   486.82    0.0000
  16      2.6504   467.79    0.0000
  17      2.6909   460.75    0.0001
  18      2.7270   454.65    0.0000
  19      2.7367   453.04    0.0004
  20      2.7996   442.87    0.0000
   1      1.4962   828.64    0.0034
   2      1.6848   735.91    0.0001
   3      1.6974   730.45    0.0005
   4      1.7378   713.47    0.0002
   5      1.7385   713.18    0.0007
   6      1.8086   685.51    0.0060
   7      2.0433   606.78    0.0102
   8      2.0607   601.65    0.0032 
   9      2.0970   591.24    0.0045 
  10      2.1033   589.48    0.0184 
  11      2.2396   553.61    0.0203 
  12      2.2850   542.61    1.1579 
  13      2.3262   532.99    0.0022 
  14      2.6288   471.64    0.0039 
  15      2.6464   468.51    0.0051 
  16      2.7435   451.92    0.0001 
  17      2.7492   450.98    0.0002 
  18      2.8945   428.34    0.0010 
  19      2.9344   422.52    0.0001 
  20      2.9447   421.04    0.0007 

预期输出:

11      2.2878   541.93    1.1090 
12      2.2850   542.61    1.1579 

每个 n 区间只有一个最高(唯一)值。

答案1

通过awk

NR%20==1 {max=$4 ; line=$0}
{ if ($4>max) {max=$4;line=$0} }
NR%20==0 {print line}

答案2

有了 GNUsort和 GNU split,你可以做到

split -l 20 file.txt --filter "sort -nk 4|tail -n 1"

该文件split以 20 个 ines 的数据包进行 ted l,然后该filter选项通过给定的命令过滤每个数据包,因此它们会在第 4 个 ey 处以数字方式sort进行 ed ,并且仅提取由 提取的最后一行(最高值)。nktail

答案3

将 DSU(装饰/排序/取消装饰)习惯用法与任何 awk+sort+cut 一起使用:

$ awk -v OFS='\t' '(NR==1) || ($1<p){b++} {p=$1; print b, $0}' file |
    sort -k5,5rn | awk '!seen[$1]++' | sort -k1,1n | cut -f2-
  11      2.2878   541.93    1.1090
  12      2.2850   542.61    1.1579

https://stackoverflow.com/questions/71691113/how-to-sort-data-based-on-the-value-of-a-column-for-part-multiple-lines-of-af/71694367#71694367有关 DSU 的更多信息。

正如 @StéphaneChazelas 的评论中提到的,如果你有 GNU 排序,那么你可以将上面的内容缩写为:

awk -v OFS='\t' '(NR==1) || ($1<p){b++} {p=$1; print b, $0}' file |
    sort -k5,5rn | sort -suk1,1n | cut -f2-

相关内容