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
    • 最新
    • 标签
主页 / unix / 问题 / 419443
Accepted
Age87
Age87
Asked: 2018-01-25 11:49:54 +0800 CST2018-01-25 11:49:54 +0800 CST 2018-01-25 11:49:54 +0800 CST

根据列中 TRUE 值的比例从 TRUE/FALSE 矩阵中提取列

  • 772

我有一个像下面这样的文本文件,尽管它有很多列。我想提取具有特定比例/数量的 TRUE 值的列名,例如 9 行中有 2 行具有 TRUE 的列(具有 TRUE/FALSE 值)。

或者,最好提取具有至少一定数量(例如 2)的 TRUE 值的列。在上面的示例中,它将是具有 TRUE 值的 2 到可能的 9 行的列。应该可以推广到具有不同行数的文件。

谢谢!

输入文件示例:

Comparison  MT  group1  group1.1    group1.2    group1.3    group1.4    group1.5    group1.6    group1.7    group1.8    group1.9
BP:HA      FALSE FALSE  FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        TRUE
CB:HA      FALSE TRUE   FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        FALSE 
HA:PI      TRUE  TRUE   FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        FALSE 
AL:GR      FALSE FALSE  FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        FALSE 
AL:LA      TRUE  FALSE  FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        FALSE 
AL:PL      FALSE FALSE  FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       TRUE         FALSE 
GR:PP      FALSE FALSE  FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        FALSE 
LA:PP      TRUE  FALSE  FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        TRUE
PL:PP      FALSE FALSE  FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE       FALSE        TRUE

具有 2 个或更多 TRUE 值的列的期望结果:

输出文件:

MT
group1
group1.9
bash text-processing
  • 3 3 个回答
  • 340 Views

3 个回答

  • Voted
  1. Alexander
    2018-01-25T12:48:14+08:002018-01-25T12:48:14+08:00

    TRUE这是使用 bash挑选出具有足够 实例的列的一种方法:

    min_true=3; \
    max_col=12; \
    for col in $(seq 2 $max_col); do \
      sed 's,    ,.,g;s,   ,.,g' "$filename" | \
        tail -n+2 | \
        cut -d. -f$col > /tmp/f; \
      count=$(grep TRUE /tmp/f | wc -l); \
      if [ "$count" -ge "$min_true" ]; then \
        echo "Column $(($col-1)): $count out of $(echo $(wc -l </tmp/f))"; \
        cat /tmp/f; \
      fi; \
    done
    

    可以对输出进行 grep 搜索,如“3 out of 9”之类的字符串,以获取列号(从 0 开始计数):

    Column 1: 3 out of 9
    FALSE
    FALSE
    TRUE
    FALSE
    TRUE
    FALSE
    FALSE
    TRUE
    FALSE
    
    • 1
  2. Best Answer
    user232326
    2018-01-25T13:21:46+08:002018-01-25T13:21:46+08:00

    扫描所有列并为每列累积“TRUE”的计数。
    最后,打印所有等于或大于设定点的列:

    #!/bin/bash
    awk -vprop="${1:-0.3}" '
            NR==1{split($0,fields);next};
            {for(i=2;i<=NF;i++){  if($i=="TRUE" ){t[i]++};
                                  if($i=="FALSE"){f[i]++}
                               }
            }
            END{
                for(j in t)
                if( (1/(1+f[j]/t[j])) >= prop){
                    printf("%-10s\t%s\t%s\n",fields[j],j,1/(1+f[j]/t[j]) )
                }
            }' infile
    

    执行时(对于您提供的数据):

    $ ./script  0.001
    MT              i=2     t=3     f=6     p=0.333
    group1          i=3     t=2     f=7     p=0.222
    group1.8        i=11    t=1     f=8     p=0.111
    group1.9        i=12    t=3     f=6     p=0.333
    

    第 2 列 (MT) 有超过 1 个 TRUE 值:实际上有 3 个。
    第 3 列 (group1) 有 2 个 TRUE 值。
    第 11 列 (group1.8) 有 1 个 TRUE 值。第 12 列 (group1.9) 有 3 个 TRUE 值。

    如果您不提供比例,则默认为 0.3。

    $ ./script
    MT              i=2     t=3     f=6     p=0.333
    group1          i=3     t=2     f=7     p=0.222
    group1.9        i=12    t=3     f=6     p=0.333
    
    • 1
  3. Kusalananda
    2018-06-18T21:47:24+08:002018-06-18T21:47:24+08:00
    $ awk -v p='10' 'NR==1 { split($0,cols); next }
                     { 
                         for (i=2; i<=NF; ++i)
                             nt[i] += ($i == "TRUE" ? 1 : 0 )
                     }
                     END {
                         for (i=2; i<=NF; ++i) {
                             cp = 100*nt[i]/NR
                             if (cp > p) printf("%-20s %.2f%%\n", cols[i], cp)
                         }
                     }' file
    MT                   30.00%
    group1               20.00%
    group1.9             30.00%
    

    该awk程序采用一个参数,该参数是显示列标题所需p的百分比。TRUE

    从第一行开始,它将所有列标题保存到数组cols中。然后它会总结该单词TRUE在每一列中出现的次数。最后,它计算TRUE每列中行的百分比,并将其cp与 进行比较p。如果大于给定p值,则输出列名和百分比。

    • 0

相关问题

  • 从文本文件传递变量的奇怪问题

  • 虽然行读取保持转义空间?

  • `tee` 和 `bash` 进程替换顺序

  • 运行一个非常慢的脚本直到它成功

  • 如何更改字符大小写(从小到大,反之亦然)?同时[重复]

Sidebar

Stats

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

    如何将 GPG 私钥和公钥导出到文件

    • 4 个回答
  • Marko Smith

    ssh 无法协商:“找不到匹配的密码”,正在拒绝 cbc

    • 4 个回答
  • Marko Smith

    我们如何运行存储在变量中的命令?

    • 5 个回答
  • Marko Smith

    如何配置 systemd-resolved 和 systemd-networkd 以使用本地 DNS 服务器来解析本地域和远程 DNS 服务器来解析远程域?

    • 3 个回答
  • Marko Smith

    如何卸载内核模块“nvidia-drm”?

    • 13 个回答
  • Marko Smith

    dist-upgrade 后 Kali Linux 中的 apt-get update 错误 [重复]

    • 2 个回答
  • Marko Smith

    如何从 systemctl 服务日志中查看最新的 x 行

    • 5 个回答
  • Marko Smith

    Nano - 跳转到文件末尾

    • 8 个回答
  • Marko Smith

    grub 错误:你需要先加载内核

    • 4 个回答
  • Marko Smith

    如何下载软件包而不是使用 apt-get 命令安装它?

    • 7 个回答
  • Martin Hope
    rocky 如何将 GPG 私钥和公钥导出到文件 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Wong Jia Hau ssh-add 返回:“连接代理时出错:没有这样的文件或目录” 2018-08-24 23:28:13 +0800 CST
  • Martin Hope
    Evan Carroll systemctl 状态显示:“状态:降级” 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim 我们如何运行存储在变量中的命令? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S 为什么 /dev/null 是一个文件?为什么它的功能不作为一个简单的程序来实现? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 如何从 systemctl 服务日志中查看最新的 x 行 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - 跳转到文件末尾 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla 为什么真假这么大? 2018-01-26 12:14:47 +0800 CST
  • Martin Hope
    Christos Baziotis 在一个巨大的(70GB)、一行、文本文件中替换字符串 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Bagas Sanjaya 为什么 Linux 使用 LF 作为换行符? 2017-12-20 05:48:21 +0800 CST

热门标签

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

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

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve