截断 CSV 标题名称

Posted

技术标签:

【中文标题】截断 CSV 标题名称【英文标题】:Truncate CSV Header Names 【发布时间】:2022-01-14 13:26:11 【问题描述】:

我正在寻找一种相对简单的方法来将 CSV 标头名称截断为给定的最大长度。例如像这样的文件:

one,two,three,four,five,six,seven
data,more data,words,,,data,the end

可以将所有标题名称限制为最多 3 个字符并变为:

one,two,thr,fou,fiv,six,sev
data,more data,words,,,data,the end

要求:

只有第一行受到影响 我不知道标头会是什么,所以它必须动态读取和写入值和长度

我用 awk 和 sed 尝试了一些东西,但都不精通。我找到的最接近的是这个 sn-p:

csvcut -c 3 file.csv |
sed -r 's/^"|"$//g' |
awk -F';' -vOFS=';' ' for (i=1; i<=NF; ++i) $i = substr($i, 0, 2)   printf("\"%s\"\n", $0) ' >tmp-3rd

但它专注于列,而且感觉比使用 csvcut 更复杂。

感谢任何帮助。

【问题讨论】:

awk: awk 'BEGIN FS=OFS="," NR==1 for(i=1; i&lt;=NF; i++) $i=substr($i, 1, 3) 1' file 谢谢@cyrus。我实际上需要添加一些逻辑来放回任何被截断的双引号,并确保不以空格结尾。它有点乱,但这是一个 awk 业余爱好者想出的:awk 'function rtrim(s) sub(/[ \t\r\n]+$/, "", s); return s BEGIN FS=OFS="," NR==1 for(i=1; i&lt;=NF; i++) if(length($i)&gt;62) $i=rtrim(substr($i, 1, 62))"\"" else $i 1' file(现在修剪为 62 个字符) 【参考方案1】:

使用 GNU sed:

sed -E '1s/([^,]1,3)[^,]*/\1/g' file

输出:

一、二、thr、fou、fiv、六、sev 数据,更多数据,单词,,,数据,结束

请参阅:man sed 和 The Stack Overflow Regular Expressions FAQ

【讨论】:

【参考方案2】:

使用您展示的示例,请尝试关注awk 程序。简单的解释是,将字段分隔符和输出字段分隔符设置为, 然后在第一行根据要求将第一行的每个字段缩短为 3 个字符并打印它们(第一行最后一个字段之后的新行),打印其余的线原样。

awk '
BEGIN  FS=OFS="," 
FNR==1
  for(i=1; i<=NF; i++)
    printf("%s%s",substr($i, 1, 3),(i==NF?ORS:OFS))
  
  next

1
' Input_file

【讨论】:

以上是关于截断 CSV 标题名称的主要内容,如果未能解决你的问题,请参考以下文章

用 Csv.Document 截断的电源查询文本

phpMyAdmin,在导入 csv 时,文本被截断

Python CSV 编写器截断长数字

从 CSV 复制到访问时,避免数字被截断

读取 csv 文件时出错(unicode 错误)“unicodeescape”编解码器无法解码位置 2-3 中的字节:截断 \UXXXXXXXX 转义 [重复]

当我将 pandas 数据框保存为 csv 文件时,从 18 位长的列中截断 3 位