使用awk提取具有多个名称的列数据(UNIX)

bxjv4tth  于 2023-08-04  发布在  Unix
关注(0)|答案(2)|浏览(124)

嘿,我使用Linux比较新,我有一个大型数据集,有5 k列,所有列都有不同的名称,比较患者数据。我想从其他组(如BC,PR...有大约100个成员为PC所有标记为PC *。其中 * 是案例编号。
数据看起来像这样(尽管分隔符= \t):
| 公司简介|BC0011| PC0023| PC0013| PR0007| PR0053| PR0053 |
| --|--|--|--|--|--| ------------ |
| 1.177703095| -1.32116828 | -2.176250582 | -2.079342976 | -1.427146954 |10.64102737| 10.64102737 |
| 1.177703095| -1.32116828 | -2.176250582 | -2.079342976 | -1.427146954 |10.64102737| 10.64102737 |
| 1.177703095| -1.32116828 | -2.176250582 | -2.079342976 | -1.427146954 |10.64102737| 10.64102737 |
我想得到的是(同样使用分隔符= \t):
| PC0023| PC0013| PC0013 |
| --|--| ------------ |
| -2.176250582 | -2.079342976 | -2.079342976 |
| -2.176250582 | -2.079342976 | -2.079342976 |
| -2.176250582 | -2.079342976 | -2.079342976 |
到目前为止,我尝试了:

$ awk -F/t -v col=*PC 'NR==1{for(i=1;i<=NF;i++){if($i==col){c=i;break}} print $c} NR>1{print $c}' data.txt > pcData.txt

字符串
但是,由于某些原因,这并没有对数据进行子集化,我最终会返回所有的列。
我不知道该把什么放进col=?才能让这一切顺利。
谢谢你的帮助!

c0vxltue

c0vxltue1#

第一个问题是输入字段定界符(-F/t);标签符号错误;几个选择:-F$'\t'BEGIN{}块(例如,BEGIN { FS="\t" });因为看起来你想维护一个制表符作为输出字段的分隔符,那么有一个想法:

# replace

awk -F/t 'NR==1 ....

# with

awk 'BEGIN { FS=OFS="\t" } NR==1 ....

字符串
第二个问题是检查以PC开头的列名;你可能会遇到一些问题,比如awk不能理解*PC的含义;由于您想了解以PC * 开头的列名,有一个想法:

awk -v col='PC' 'NR==1{for (i=1;i<=NF;i++) if ( index($i,col)==1 ) ....'


第三个问题是你想构建一个列表(一个数组怎么样?存储感兴趣的列的列表;你现在在第一个匹配上打破了NR==1循环,你想做的是跟踪所有匹配的列号(i);因为你也想保留第一列,比如:

if ( index($i,col)==1 || i==1 ) cols[++c]=i


.然后对于所有输入行,打印由数组中的数字表示的列。
将所有这些都整合到一个完整的脚本中(并更改一些名称):

awk -v pfx='PC' '
BEGIN { FS=OFS="\t" }
NR==1 { for (i=1;i<=NF;i++)
            if ( (index($i,pfx)==1) || i==1)
               cols[++c]=i
      }
      { for (i=1;i<=c;i++)
            printf "%s%s", (i==1 ? "" : OFS), $(cols[i])
        print ""
      }
' data.txt


这产生:

ID_REF  PC0023  PC0013
Gene1   -2.176250582    -2.079342976
Gene2   -2.176250582    -2.079342976
Gene3   -2.176250582    -2.079342976

nsc4cvqm

nsc4cvqm2#

TXR Lisp中:

$ txr getpc.tl < data
ID_REF  PC0023  PC0013
Gene1   -2.176250582    -2.079342976
Gene2   -2.176250582    -2.079342976
Gene3   -2.176250582    -2.079342976

字符串
代码:

(let* ((header (spl "\t" (get-line)))
       (wanted-cols (where (f^$ #/ID_REF|PC.*/) header)))
  (put-line (join-with "\t" (select header wanted-cols)))
  (whilet ((line (get-line))
           (row (if line (spl "\t" line))))
    (put-line (join-with "\t" (select row wanted-cols)))))


where函数返回某个 predicate 为真的序列的索引(从零开始的位置)。select函数是它的伙伴,它从序列中选择这些位置。

相关问题