【问题标题】:Truncate CSV Header Names截断 CSV 标题名称
【发布时间】: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 个字符)

标签: csv awk sed


【解决方案1】:

使用 GNU sed:

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

输出:

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

请参阅:man sedThe 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-24
      相关资源
      最近更新 更多