是否有命令行咒语可以删除 CSV 文件中的一列?

是否有命令行咒语可以删除 CSV 文件中的一列?

具有以下内容的文件:

1111,2222,3333,4444
aaaa,bbbb,cccc,dddd

我寻求获得一个与原始文件相同但缺少第 n 列的文件,例如 n = 2 (或者可能是 3)

1111,2222,4444
aaaa,bbbb,dddd

或者,对于 n = 0(或者可以是 1)

2222,3333,4444
bbbb,cccc,dddd

真实的文件可能有千兆字节长,有数万列。

与往常一样,在这种情况下,我怀疑命令行魔术师可以提供一个优雅的解决方案......:-)

在我的实际案例中,我需要删除 2 个第一列,这可以通过按顺序删除第一列两次来完成,但我认为概括一下会更有趣。

答案1

我相信这是 GNU coreutils 特有的:

$ cut --complement -f 3 -d, inputfile
1111,2222,4444
aaaa,bbbb,dddd

通常,您可以通过 -f 指定所需的字段,但通过添加 --complement ,您自然可以颠倒含义。来自“人切”:

--complement
    complement the set of selected bytes, characters or fields

需要注意的是:如果任何列包含逗号,则会抛出 cut off,因为 cut 不是与电子表格相同的 CSV 解析器。许多解析器对于如何处理 CSV 中的转义逗号有不同的想法。对于简单的 CSV 情况,在命令行上,cut 仍然是可行的方法。

答案2

如果数据只是由逗号分隔的列组成:

cut -d , -f 1-2,4-

您也可以使用 awk,但这有点尴尬,因为虽然清除字段很容易,但删除分隔符需要一些工作。如果你没有空字段,那也不算太糟糕:

awk -F , 'BEGIN {OFS=FS}  {$3=""; sub(",,", ","); print}'

如果您有实际的 CSV,如果正确引用,逗号可以出现在字段内,那么您需要真正的 CSV 库

答案3

使用 CSV 感知工具从无标题 CSV 输入文件中删除前两列:

$ cat file
1111,2222,3333,4444
aaaa,bbbb,cccc,dddd
$ mlr --csv -N cut -x -f 1,2 file
3333,4444
cccc,dddd

-x操作选项cut磨坊主( mlr) 导致操作排除命名字段(在本例中为字段号 1 和 2)。如果 CSV 数据有标题,我们就可以使用命名字段-f-N在这种情况下也需要删除该选项)。

由于 Miller 支持 CSV,因此它可以处理包含嵌入逗号、引号和换行符的正确引用字段。

答案4

尝试使用以下命令删除使用索引的列。

dropColumnCSV --index=0 --file=file.csv

如果列用逗号分隔,这将起作用,如下所示sed函数内部使用命令来删除字符串。

dropColumnCSV() {
  # argument check
  while [ $# -gt 0 ]; do
    case "$1" in
      --index=*)
        index="${1#*=}"
        ;;
      --file=*)
        file="${1#*=}"
        ;;
      *)
        printf "* Error: Invalid argument. *\n"
        return
    esac
    shift
  done

  # file check
  if [ ! -f $file ]; then
        printf "* Error: $file not found.*\n"
        return
  fi

  # sed remove command index zero
  if [[ $index == 0 ]]; then
    sed -i 's/\([^,]*\),\(.*\)/\2/' $file

  # sed remove command index greater than zero
  elif [[ $index > 0 ]]; then
    pos_str=$(for i in {1..$(seq "$index")}; do echo -n '[^,]*',; done| sed 's/,$//') ;
    sed -i 's/^\('$pos_str'\),[^,]*/\1/' $file
  fi
}

相关内容