我有以下输入csv文件:
"aaa","1","xxx" "ccc, Inc.","6100","yyy" "bbb","609","zzz"
我希望按第二列排序为数字, 我试过了
sort --field-separator=',' --key=2n
问题在于,由于引用了所有值,因此它们无法通过-n(数字)选项正确排序。有解决方案吗?
答案 0 :(得分:4)
一个小技巧,它使用双引号作为分隔符:
sort --field-separator='"' --key=4 -n
答案 1 :(得分:2)
将您的示例放入名为sort2.txt的文件中我发现以下内容效果很好
sort -t'"' -k4n sort2.txt
使用sort和以下命令(感谢Jonathan的改进)
希望这有帮助!
答案 2 :(得分:2)
对于引用的csv
,请使用具有正确csv
解析器的语言。以下是使用perl
的示例。
perl -MText::ParseWords -lne '
chomp;
push @line, [ parse_line(",", 0, $_) ];
}{
@line = sort { $a->[1] <=> $b->[1] } @line;
for (@line) {
local $" = qw(",");
print qq("@$_");
}
' file
<强>输出:强>
"aaa","1","xxx"
"bbb","609","zzz"
"ccc, Inc.","6100","yyy"
<强>解释强>
chomp
功能从输入中删除新行。 END
块中,对第二列上的数组数组进行排序,并将其分配给原始数组数组。 ","
,然后使用前面和尾随"
打印它以创建原始格式的行。 答案 3 :(得分:0)
没有一个非常简单的解决方案。如果你做出一些合理的假设,那么你可以考虑:
sed 's/","/^A/g' input.csv |
sort -t'^A' -k 2n |
sed 's/^A/","/g
这将","
序列替换为 Control-A (在代码中显示为^A
),然后将其用作sort
中的字段分隔符(第2列上的数字排序,然后再次将 Control-A 字符替换为","
。
如果您使用bash
,则可以使用ANSI C quoting机制$'\1'
将控制字符明显嵌入到脚本中;你只需要在转义之前完成单引号字符串,然后重新启动它:
sed 's/","/'$'\1''/g' input.csv |
sort -t$'^A' -k 2n |
sed 's/'$'\1''/","/g
或者使用双引号而不是单引号,但由于您要替换的双引号,这会变得混乱。但您只需逐字输入字符,vim
等编辑就会很乐意向您展示。
答案 4 :(得分:0)
有时,只有在必要时才会引用CSV文件中的值。在这种情况下,使用"
作为分隔符是不可靠的。
示例:
"Forest fruits",198
Apples,456
bananas,67
使用awk
,sort
和cut
,您可以对第一列进行排序原始文件:
awk -F',' '{
a = $1; # or the column index you want
gsub(/(^"|"$)/, "", a);
print a","$0
}' file.csv | sort -k1 | cut -d',' -f1 --complement
这将使您想要在前面排序的列没有引号,然后按照您想要的方式对其进行排序,并在最后删除此列。