Unix 根据从另一个文件中选择的标题从文件中提取列
我想在awk中解决以下问题。我有一个大的文本表,逗号分隔,由100k行和5k列组成。第一行是标题,第一列是记录id。然后我有第二个文本文件,其中包含第一个文件中标题的子集。我想提取第一个文件的所有列,其标题包含在第二个文件中给出的列表中。这里是输入和所需输出的示例: DATA.TXTUnix 根据从另一个文件中选择的标题从文件中提取列,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
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