我正尝试根据两个条件筛选包含列的文本文件。由于文件的大小,我无法使用列号(因为有数千列且未编号),但需要使用列名。我已搜索并尝试想出多种方法来完成此操作,但命令行中没有返回任何内容。
以下是我尝试过的几种方法:awk '($colname1==2 && $colname2==1) { count++ } END { print count }' file.txt
,根据列的条件筛选出列
以及head -1 file.txt | tr '\t' | cat -n | grep "COLNAME
来尝试并返回与该列相关的可能的列号。
示例文件如下:
ID ad bd
1 a fire
2 b air
3 c water
4 c water
5 d water
6 c earth
输出为:2(ad=c和bd=水的计数)
4条答案
按热度按时间2sbarzqh1#
与您的输入文件和隐含条件,这应该工作
也可以用脚本中的值替换c1和c2。
查找列索引,您可以运行
或者用这条链子
尽管可能由于正则表达式匹配而出现假阳性...
您可以重写
awk
以使其更加简洁jmo0nnb32#
正如我在前面的评论中提到的,https://unix.stackexchange.com/a/359699/133219的答案显示了如何做到这一点:
我假设你的输入是制表符分隔的,因为你的问题中的命令中的
tr '\t'
看起来像是你试图将制表符转换成换行符,将列名转换成数字。如果我错了,它们只是被任何白色链分隔,那么从上面删除-F'\t'
。lp0sw83n3#
使用
miller
工具包可以使用列名操作制表符分隔的文件。下面是一行程序,它过滤制表符分隔的文件(分隔符使用--tsv
指定),并将结果与标头一起写入STDOUT。标头使用tail
删除,行数使用wc
计数。图纸:
miller
manual注意,
miller
可以很容易地安装,例如,使用conda
,如下所示:apeeds0o4#
多年来,我一直在烦恼,Unix中没有简洁的方法来完成这类事情,尽管miller是一个很好的工具。最近,我编写了
pick
来按名称选择列,并按名称修改、合并和添加它们,以及使用列名按子句过滤行。使用pick
解决上述问题的方法是默认情况下,pick打印所选列的标题,
-h
表示忽略它。要打印列,您只需在命令行中命名它们,例如:Pick有许多模式,所有这些模式都侧重于用最少的语法操作列和选择/过滤行。