Answers:
仅使用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])
$ apt-get install csvtool
然后转换
$ csvtool transpose input.csv > ouput.csv
或在管道中
$ ... | csvtool transpose - | ...
... | csvtranspose | ...
语法角度来看,只会击败它。
快速又肮脏的bash解决方案:
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++))
}
for ((i=1; i<=$num_cols; ++i)); do paste -s -d, <(cut -f$i -d, file.txt); done
this "is" example
单元格进行了编码"this ""is"" example"
我不相信该解决方案是否可以正确处理此类情况
给定建议的限制(不加引号,没有嵌入式逗号),它在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将被删除;其他示例未解决此细节。
python
,b)的ruby
可移植性不及python
,并且c)这也说明了如何传递输入/输出文件。Bravo @luikore,欢迎使用Unix&Linux。请坚持。