Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unix 根据从另一个文件中选择的标题从文件中提取列_Unix_Awk - Fatal编程技术网

Unix 根据从另一个文件中选择的标题从文件中提取列

Unix 根据从另一个文件中选择的标题从文件中提取列,unix,awk,Unix,Awk,我想在awk中解决以下问题。我有一个大的文本表,逗号分隔,由100k行和5k列组成。第一行是标题,第一列是记录id。然后我有第二个文本文件,其中包含第一个文件中标题的子集。我想提取第一个文件的所有列,其标题包含在第二个文件中给出的列表中。这里是输入和所需输出的示例: DATA.TXT ID, head1, head2, head3, head4 1, 25.5, 1364.0, 22.5, 13.2 2, 10.1, 215.56, 1.15, 22.2 LI

我想在awk中解决以下问题。我有一个大的文本表,逗号分隔,由100k行和5k列组成。第一行是标题,第一列是记录id。然后我有第二个文本文件,其中包含第一个文件中标题的子集。我想提取第一个文件的所有列,其标题包含在第二个文件中给出的列表中。这里是输入和所需输出的示例:

DATA.TXT

   ID, head1, head2, head3, head4  
    1, 25.5, 1364.0, 22.5, 13.2  
    2, 10.1, 215.56, 1.15, 22.2  
LIST.TXT

head1  
head4  
期望输出:

ID, head1, head4  
1, 25.5, 13.2  
2, 10.1, 22.2

任何人都可以给我一些建议,告诉我如何在awk中或通过unix脚本解决这个问题?提前感谢您的帮助

有一个有用的
awk
脚本,可用于从csv文件中提取特定列名

我稍微修改了它,以便它可以从另一个文件中读取列名。将下面的脚本另存为
dataExtractor.sh

#!/bin/bash

DATAFILE=${1:-data.txt}
COLUMNFILE=${2:-list.txt}

awk -F, -v colsFile="$COLUMNFILE" '
   BEGIN {
     j=1
     while ((getline < colsFile) > 0) {
        col[j++] = $1
     }
     n=j-1;
     close(colsFile)
     for (i=1; i<=n; i++) s[col[i]]=i
   }
   NR==1 {
     for (f=1; f<=NF; f++)
       if ($f in s) c[s[$f]]=f
     next
   }
   { sep=""
     for (f=1; f<=n; f++) {
       printf("%c%s",sep,$c[f])
       sep=FS
     }
     print ""
   }
' "$DATAFILE"

我有一个想法,但由于我对shell编程没有经验(也不知道awk),这看起来像是以一种荒谬的方式重新发明了一些轮子:

$ cat DATA.TXT 
ID, head1, head2, head3, head4
1, 25.5, 1364.0, 22.5, 13.2
2, 10.1, 215.56, 1.15, 22.2

$ cat LIST.TXT 
head1
head4

$ cols=($(sed '1!d;s/, /\n/g' DATA.TXT | grep -nf LIST.TXT | sed 's/:.*$//'))

$ cut -d ',' -f 1$(printf ",%s" "${cols[@]}") DATA.TXT 
ID, head1, head4
1, 25.5, 13.2
2, 10.1, 22.2

另外,我使用了一些关于bash数组的基本概念,这些概念来自于和answers。

LIST.TXT文件中是否需要ID?(如果您可以包含它,它将简化解决方案)。祝你好运(如果这是真的,请编辑您的问题)。@Sheller在我的情况下,解决方案比现在更简单:)不,LIST.TXT没有任何ID字段,按原样提供。输出中的ID是DATA.TXT中的ID@你的解决方案确实(显然)很简单。一旦我明白了为什么每一个符号都在它所在的地方!:)这很好用!谢谢我也有一些材料来思考和理解你做了什么@我很乐意帮忙。如果你不理解我在那里做了什么,请尽管问。(提示:将其拆开,看看会发生什么情况,从
sed'1!d;s/,/\n/g'DATA.TXT
等开始)此脚本唯一地匹配最大前三个数字,例如,如果DATA.TXT文件中的标题如下所示:ID,1002010021002310024 list.TXT 10020 10022 10023,那么它将不打印到10023,而是打印10024,请检查此问题当LIST.TXT中的colname包含数字和特殊字符(例如34-0.0)时,此问题似乎不起作用。它能适应这些吗?谢谢你的回答。我使用了下面更紧凑的一个,但现在我看到了我在awk尝试中出错的地方!非常有用!!如果我们想在输出中也看到ID,head1,head4,怎么样?看起来ID、头1、头4在输出部分消失了。
$ cat DATA.TXT 
ID, head1, head2, head3, head4
1, 25.5, 1364.0, 22.5, 13.2
2, 10.1, 215.56, 1.15, 22.2

$ cat LIST.TXT 
head1
head4

$ cols=($(sed '1!d;s/, /\n/g' DATA.TXT | grep -nf LIST.TXT | sed 's/:.*$//'))

$ cut -d ',' -f 1$(printf ",%s" "${cols[@]}") DATA.TXT 
ID, head1, head4
1, 25.5, 13.2
2, 10.1, 22.2