是否有命令行实用程序来转置csv文件?


16

给定这样的文件

First,Last,Age
Cory,Klein,27
John Jacob,Smith,30

是否有命令行实用程序来转置内容,因此输出看起来像这样

First,Cory,John Jacob
Last,Klein,Smith
Age,27,30

Answers:


6
ruby -rcsv -e 'puts CSV.parse(STDIN).transpose.map &:to_csv' < in.csv > out.csv

给定这个问题的年龄,我将证明我接受此更改是有道理的:a)这个答案比Gilles的答案简洁得多python,b)的ruby可移植性不及python,并且c)这也说明了如何传递输入/输出文件。Bravo @luikore,欢迎使用Unix&Linux。请坚持。
科里·克莱因

请注意,在csv中必须引用字段
yosefrow

@yosefrow无需报价。在发布此答案之前,我已经测试了命令。
luikore

好的,应该说“可以”。在我引用所有字段之前,它对我没有用。可能与我的数据内容有关
yosefrow

16

仅使用POSIX工具很难完成CSV解析,除非您使用不带引号的简化CSV变体(这样逗号就不会出现在字段中)。即使那样,使用awk或其他文本处理工具似乎也不容易完成此任务。您可以将Perl与Text::CSV,Python与csv,R与read.csv,Ruby与CSV一起使用,…(所有这些都是Perl各自语言的标准库的一部分)。

例如,在Python中:

import csv, sys
rows = list(csv.reader(sys.stdin))
writer = csv.writer(sys.stdout)
for col in xrange(0, len(rows[0])):
    writer.writerow([row[col] for row in rows])


3

快速又肮脏的解决方案:

c=1
file=file.txt
num_lines=$(wc -l < "$file")

for ((i=0; i<num_lines; i++)) {
    cut -d, -f$c "$file" | paste -sd ','
    ((c++))
}

/ tmp / l代表什么?此外,通过列而不是行遍历不是更简单的方法吗for ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
iruvar

请注意,这适用于OP的输入,但这仅是因为其数据具有相同的行数和列数,通常情况并非如此。
托克兰

csv具有有关dpuble引号的规范,即对this "is" example单元格进行了编码"this ""is"" example"我不相信该解决方案是否可以正确处理此类情况
Grzegorz Wierzowiecki

0

给定建议的限制(不加引号,没有嵌入式逗号),它在awk中很简单(因为在perl中不考虑中的一千行CSV.pm,中的2300行csv.rb-python中只有450行csv.py)。

这是awk的示例:

#!/usr/bin/awk -f
BEGIN { width=0; }
{
    max = split($0, list, ",");
    # printf "%d:%s\n", NR, $0;
    if (width < max)
        width = max;
    for (n = 1; n <= max; ++n) {
        sub("^[     ]*","",list[n]);
        sub("[  ]*$","",list[n]);
        # printf "\t%d:%s\n", n, list[n];
        if ( columns[n] != "" ) {
            columns[n] = columns[n] ", ";
        }
        columns[n] = columns[n] list[n];
    }
}
END {
    # printf "%d columns\n", width;
    for (n = 1; n <= width; ++n) {
        printf "%s\n", columns[n];
    }
}

顺便说一句:给定的示例有多余的空间,假定OP将被删除;其他示例未解决此细节。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.