把这个问题作为以前的答案重新发布是不起作用的,因为缺乏最小的可重复的例子(mea culpa)。对不起,如果这是基本的,但我不能让它工作,并花了很多时间尝试。
请看我之前发布的问题:Unix shell script select columns in csv file based on headers from another csv file
我创建了一个csv头文件,其中头文件中的每一行都是我想要的列的名称。在data_file.csv本身中,第一行显示如下,每个列标题都在第一行中,数据用引号括起来:
echo $(head -n 1 data_file.csv)
"eid","132421-0.0","132422-0.0","132423-0.0", ...
我创建的头文件如下所示,每个列头都是一行,没有引号。
eid
24500-0.0
24503-0.0
24503-1.0
4526-0.0
4526-1.0
注意没有引号。如果我尝试(手动)将引号添加到headers.csv文件中,然后再次使用$cat,我会在每个标题行上得到三个引号(不知道为什么)。
"""eid"""
"""24500-0.0"""
"""24500-1.0"""
"""24503-0.0"""
"""24503-1.0"""
"""4526-0.0"""
"""4526-1.0"""
我所要做的就是从庞大的data_file.csv(有28,000列)中提取20列,其标题列在headers.csv文件中。然后我可以把它们加载到R中,然后就可以了。
数据本身是字符和数字的混合,每个字段都用引号括起来。
@glenn_jackman提出了以下解决方案,但我没有指出报价:
awk '
BEGIN {FS = OFS = ","}
NR == FNR {wanted[$0] = 1; next}
FNR == 1 {
ncol = 0
for (i = 1; i <= NR; i++)
if ($i in wanted)
columns[++ncol] = i
}
{
for (i = 1; i <= ncol; i++)
printf "%s%s", $columns[i], OFS
print ""
}
' headers.csv data_file.csv > selected_data_file.csv
因此,此操作失败,我得到一个空白的selected_data_file. csv。
我正在寻找的输出是:
$ cat selected_data_file.csv
"eid", "24500-0.0", "24503-0.0", "24503-1.0", "4526-0.0", "4526-1.0"
"AB1","1","a","0","1.2",""
行数与data_file. csv相同。
不知道如何使它更清晰或更可复制比...非常感谢您的帮助。
2条答案
按热度按时间oxosxuxt1#
从问题和OP的评论中得出的假设/理解:
根据(上述)假设制作一些样本数据:
一个
GNU awk
(用于FPAT
支持):这产生:
iaqfqrcu2#
您在评论中指出您正在使用英国生物库数据集。Biobank为Windows和Linux提供了一个转换实用程序
ukbconv
:https://biobank.ctsu.ox.ac.uk/crystal/download.cgi根据this pdf和官方文档,给定文本文件中的字段编号列表,直接从原始文件中提取相关列为适合R的格式的命令为:
文档区分了“字段”和“列”:
例如,假设我们只想从数据集中提取字段31、20204和40000,并将其转换为csv格式。我们创建一个名为
field_list.txt
的文本文件,其内容如下:并将其放入与
ukbconv
相同的文件夹中。然后我们运行命令:结果输出将仅包含eid列以及Data-Fields 31、20204和40000的所有示例和数组组合的列(假设这些Data-Fields存在于
.enc_ukb
文件中)。为了帮助准备提供所需字段列表的文件,
ukbconv
每次运行时都会输出名为field.ukb
的文件,该文件列出了与数据集相关的所有可用字段。这可以被编辑以标识要被包括在子集中或从子集中排除的特定字段。它还讨论了“示例和数组索引”,并指出在csv的情况下:
列标题的格式为
F-I.A
,其中F
是数据字段编号,I
是示例索引,A
是数组索引这看起来像你的问题的头格式,所以它可能是,通过使用
ukbconv
,你最终会得到更多的数据比你要求的(即。额外的列)。这对你来说可能是个问题,也可能不是。