是否有命令列咒語可以刪除 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

真實的文件可能有千兆位元組長,有數萬列。

像往常一樣,在這種情況下,我懷疑命令行魔術師可以提供一個優雅的解決方案......:-)

在我的實際案例中,我需要刪除前兩列,這可以透過按順序刪除第一列兩次來完成,但我認為概括一下會更有趣。

答案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
}

相關內容