AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / ubuntu / 问题 / 1158639
Accepted
Mr. 206
Mr. 206
Asked: 2019-07-17 03:28:37 +0800 CST2019-07-17 03:28:37 +0800 CST 2019-07-17 03:28:37 +0800 CST

对每一列进行排序并在第一行中为底部 2 个值获取对应的键 ID

  • 772

这是我的工作文件。(列号和行号未知)

key_ID  col_1 col_2 col_3
AA      1     1     1
BB      56    2     7
CC      89    5     2
DD      7     77    7

我想对每列的底部 2 个值进行排序,以便key_ID 从第一列中找到它们对应的值。

期望的输出就像

col_1  col_2 col_3
AA     AA     AA
DD     BB     CC         
sort text-processing
  • 5 5 个回答
  • 84 Views

5 个回答

  • Voted
  1. pLumo
    2019-07-17T04:13:55+08:002019-07-17T04:13:55+08:00

    使用csvsql来自csvkit:

    paste \
    <(csvsql -d ' ' -S  --query "select key_ID as "col_1" from file order by col_1 limit 2" file) \
    <(csvsql -d ' ' -S  --query "select key_ID as "col_2" from file order by col_2 limit 2" file) \
    <(csvsql -d ' ' -S  --query "select key_ID as "col_3" from file order by col_3 limit 2" file)
    

    输出:

    col_1   col_2   col_3
    AA      AA      AA
    DD      BB      CC
    

    您应该可以csvkit通过以下方式安装pip:

    sudo apt install python-pip
    sudo pip install csvkit
    
    • 3
  2. Best Answer
    Ravexina
    2019-07-17T05:14:17+08:002019-07-17T05:14:17+08:00

    使用纯bash:

    #!/bin/bash
    
    DATA=/path/to/input_data
    COL_NUMS=$(head -1 $DATA | wc -w)
    
    FILES=''
    for i in $(seq 2 $COL_NUMS)
    do
      FILE=$(mktemp)     
      echo col_$((i-1)) > $FILE
      cut -f1,$i -d' ' <(tail -n +2 $DATA | tr -s ' ') | 
            sort -k2 -g | head -2 | cut -f1 -d' ' >> $FILE
    
      FILES="$FILES $FILE"
    done
    
    paste $FILES
    rm $FILES
    

    输出:

    col_1   col_2   col_3
    AA      AA      AA
    DD      BB      CC
    

    它所做的是逐个查看您的列及其标签,例如labels,col1,然后labels,col2等等。

    for i in $(seq 2 $COL_NUMS)
    do
      ...
      cut -f1,$i -d' ' <(tail -n +2 $DATA | tr -s ' ')
    

    然后它排序并找到每个组中具有两个最低值的标签,并将它们放入临时文件中。

    FILE=$(mktemp)
    ...
    sort -k2 -g | head -2 | cut -f1 -d' ' >> $FILE
    

    在执行此操作时,我们会创建所有这些文件的列表。

    FILES="$FILES $FILE"
    

    所以现在我们有一堆包含所需列表的临时文件,我们应该使用paste命令将它们放在一起并删除这些临时文件:

    paste $FILES
    rm $FILES
    
    • 3
  3. pLumo
    2019-07-17T04:21:40+08:002019-07-17T04:21:40+08:00

    与我的答案类似的想法使用csvsql, 但使用paste,sort和awk:

    paste \
     <(tail -n+2 file | sort -k2n | awk 'BEGIN{print "col_1"} NR<3{print $1}') \
     <(tail -n+2 file | sort -k3n | awk 'BEGIN{print "col_2"} NR<3{print $1}') \
     <(tail -n+2 file | sort -k4n | awk 'BEGIN{print "col_3"} NR<3{print $1}')
    

    输出:

    col_1   col_2   col_3
    AA      AA      AA
    DD      BB      CC
    
    • 1
  4. Jos
    2019-07-17T04:00:41+08:002019-07-17T04:00:41+08:00

    不是bash解决方案,但在 SQL 中,这可以很容易地完成:

    首先,创建表:

    create table working (key_ID char(2), col_1 integer, col_2 integer, col_3 integer);
    insert into working values ("AA", 1,1,1), ("BB", 56, 2,7), ("CC", 89,5,2), ("DD", 7, 77, 7);
    

    现在使用第一个和第二个值创建三个派生表,为每个表添加一个行号,并将它们连接到行号:

    set @row_num1 = 0;
    set @row_num2 = 0;
    set @row_num3 = 0;
    select col1.key_ID as col_1, col2.key_ID as col_2, col3.key_ID as col_3 from 
        (select (@row_num1 := @row_num1 + 1 ) as num,key_ID, col_1 from working order by col_1 limit 2) as col1
            join (select (@row_num2 := @row_num2 + 1 ) as num,key_ID, col_2 from working order by col_2 limit 2) as col2 on col1.num = col2.num
            join (select (@row_num3 := @row_num3 + 1 ) as num,key_ID, col_3 from working order by col_3 limit 2) as col3 on col1.num = col3.num
    

    给

    +-------+-------+-------+
    | col_1 | col_2 | col_3 |
    +-------+-------+-------+
    | AA    | AA    | AA    |
    | DD    | BB    | CC    |
    +-------+-------+-------+
    
    • 0
  5. Eric Mintz
    2019-07-17T04:11:22+08:002019-07-17T04:11:22+08:00

    tail -n +2 给你除了标题行之外的所有内容

    sort -k2 -n 对第二列进行排序 - 对其他列使用 -k3 和 -k4 重复此操作

    head -n 2 为您提供前 2 行

    tail -n +2 test | sort -k2 -n | head -n 2
    

    然后根据需要存储输出。

    • -1

相关问题

  • Nautilus“神秘地”对名称列进行排序。如何更改整理顺序?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何运行 .sh 脚本?

    • 16 个回答
  • Marko Smith

    如何安装 .tar.gz(或 .tar.bz2)文件?

    • 14 个回答
  • Marko Smith

    如何列出所有已安装的软件包

    • 24 个回答
  • Marko Smith

    无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗?

    • 25 个回答
  • Martin Hope
    Flimm 如何在没有 sudo 的情况下使用 docker? 2014-06-07 00:17:43 +0800 CST
  • Martin Hope
    Ivan 如何列出所有已安装的软件包 2010-12-17 18:08:49 +0800 CST
  • Martin Hope
    La Ode Adam Saputra 无法锁定管理目录 (/var/lib/dpkg/) 是另一个进程在使用它吗? 2010-11-30 18:12:48 +0800 CST
  • Martin Hope
    David Barry 如何从命令行确定目录(文件夹)的总大小? 2010-08-06 10:20:23 +0800 CST
  • Martin Hope
    jfoucher “以下软件包已被保留:”为什么以及如何解决? 2010-08-01 13:59:22 +0800 CST
  • Martin Hope
    David Ashford 如何删除 PPA? 2010-07-30 01:09:42 +0800 CST

热门标签

10.10 10.04 gnome networking server command-line package-management software-recommendation sound xorg

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve