【问题标题】:Print first, penultimate and last fields in CSV file打印 CSV 文件中的第一个、倒数第二个和最后一个字段
【发布时间】:2026-01-10 23:05:01
【问题描述】:

我有 20000 行和 5 列的大逗号分隔文件,我想提取特定列,但是值更多所以逗号更多,除了标题,所以如何剪切这样的列。

示例文件:

name,v1,v2,v3,v4,v5
as,"10,12,15",21,"12,11,10,12",5,7
bs,"11,15,16",24,"19,15,18,23",9,3

这是我想要的输出:

name,v4,v5
as,5,7
bs,9,3

我尝试了以下剪切命令但不起作用

cut -d, -f1,5,6

【问题讨论】:

  • 20000 并不大。二十多年前,我不会三思而后行将其放入文本编辑器并对其进行搜索替换。
  • 据我统计,您的文件有六个字段:名称和 v1 到 v5。

标签: csv unix command cut


【解决方案1】:

一般来说,对于这些场景,最好使用适当的 csv 解析器。例如,您可以在 Python 中找到它们。

但是,由于您的数据似乎刚开始就有带逗号的字段,您可以决定打印第一个字段,然后打印倒数第二个和最后一个:

$ awk 'BEGIN{FS=OFS=","} {print $1, $(NF-1), $NF}' file
name,v4,v5
as,5,7
bs,9,3

【讨论】:

  • 感谢 fedorqui,但如果我想剪掉中间的 collum(即 3rd),那该怎么办?
  • @mona 那么你必须使用 CSV 解析器,因为 bash 脚本无法很好地处理它。
【解决方案2】:

TXRLisp:

$ txr extract.tl 

extract.tl中的代码:

(mapdo
  (lambda (line)
    (let ((f (tok-str line #/"[^"]*"|[^,]+/)))
      (put-line `@[f 0],@[f 4],@[f 5]`)))
  (get-lines))

作为一个浓缩的一个班轮:

$ txr -t '(mapcar* (do let ((f (tok-str @1 #/"[^"]*"|[^,]+/)))
                     `@[f 0],@[f 4],@[f 5]`) (get-lines))' 
    

【讨论】:

    最近更新 更多