簡體   English   中英

Bash - 從 .csv 文件中刪除空列

[英]Bash - Removing empty columns from .csv file

我有一個很大的 .csv 文件,我必須在其中刪除空的列。 空,我的意思是他們有一個標題,但列的其余部分不包含任何數據。

我已經編寫了一個 Bash 腳本來嘗試執行此操作,但是遇到了一些問題。 這是代碼:

#!/bin/bash

total="$(head -n 1 Reddit-cleaner.csv | grep -o ',' | wc -l)"
i=1
count=0
while [ $i -le $total ]; do
        cat Reddit-cleaner.csv | cut -d "," -f$i | while read CMD; do if [ -n CMD ]; then count=$count+1; fi; done
        if [ $count -eq 1 ]; then
                cut -d "," -f$i --complement <Reddit-cleaner.csv >Reddit-cleanerer.csv
        fi
        count=0
        i=$i+1
done

首先我找到列數,並將其存儲起來。 然后當程序還沒有到達最后一列時,我會逐列循環。 嵌套的 while 循環檢查列中的每一行是否為空,如果有多個非空行,它將所有其他列寫入另一個文件。

我認識到這個腳本存在一些問題。 首先,count 修改發生在子shell 中,因此count 永遠不會在父shell 中修改。 其次,每次腳本找到空列時,我正在寫入的文件都會被覆蓋。

所以我的問題是我該如何解決這個問題。 我最初想擁有它,以便它根據計數逐列寫入新文件,但也不知道如何完成。

編輯:人們要求提供示例輸入和輸出。

Sample input:
User, Date, Email, Administrator, Posts, Comments
a, 20201719, a@a.com, Yes, , 3
b, 20182817, b@b.com, No, , 4
c, 20191618, , No, , 4
d, 20190126, , No, , 2

Sample output:
User, Data, Email, Administrator, Comments
a, 20201719, a@a.com, Yes, 3
b, 20182817, b@b.com, No, 4
c, 20191618, , No, 4
d, 20190126, , No, 2

在示例輸出中,除了標題 (Posts) 之外沒有任何數據的列已被刪除,而完全或部分填充的列仍然存在。

我可能誤解了這個問題(由於它缺少示例輸入和預期輸出),但這應該很簡單:

$ x="1,2,3,,4,field 5,,,six,7"
$ echo "${x//,+(,)/,}"
1,2,3,4,field 5,six,7

這需要啟用extglob bash。 否則,您可以使用外部調用sed

$ echo "1,2,3,,4,field 5,,,six,7" |sed 's/,,,*/,/g'
1,2,3,4,field 5,six,7

您的示例代碼中有很多冗余。 您應該真正考慮awk因為它已經跟蹤了當前字段計數(作為NF )和行數(作為NR ),因此您可以在每行上用一個簡單的total+=NF將其相加。 折疊空字段后, awk可以在您想要的字段編號上運行。

$ echo "1,2,3,,4,field 5,,,six,7" |awk -F ',+' '
  { printf "line %d has %d fields, the 6th of which is <%s>\n", NR, NF, $6 }'
line 1 has 7 fields, the 6th of which is <six>

這使用printf表示記錄數( NR ,當前行號),字段數( NF )和第六個字段的值( $6 ,也可以作為變量,例如$NF是final 字段,因為awk是單索引的)。

它實際上是 CSV 解析器的工作,但您可以使用此awk腳本來完成工作:

cat removeEmptyCellsCsv.awk

BEGIN {
   FS = OFS = ", "
}
NR == 1 {
   for (i=1; i<=NF; i++)
      e[i] = 1  # initially all cols are marked empty
   next
}
FNR == NR {
   for (i=1; i<=NF; i++)
      e[i] = e[i] && ($i == "")
   next
}
{
   s = ""
   for (i=1; i<=NF; i++)
      s = s (i==1 || e[i-1] ? "" : OFS) (e[i] ? "" : $i)
   print s
}

然后運行它:

awk -f removeEmptyCellsCsv.awk file.csv{,}

使用有問題提供的示例數據,它將產生以下輸出:

1, User, Date, Email, Administrator, Comments
2, a, 20201719, a@a.com, Yes, 3
3, b, 20182817, b@b.com, No, 4
4, c, 20191618, , No, 4
5, d, 20190126, , No, 2

請注意Posts列已被刪除,因為它在每條記錄中都是空的。

$ cat tst.awk
BEGIN { FS=OFS="," }
NR==FNR {
    if ( NR > 1 ) {
        for (i=1; i<=NF; i++) {
            if ( $i ~ /[^[:space:]]/ ) {
                gotValues[i]
            }
        }
    }
    next
}
{
    c=0
    for (i=1; i<=NF; i++) {
        if (i in gotValues) {
            printf "%s%s", (c++ ? OFS : ""), $i
        }
    }
    print ""
}

$ awk -f tst.awk file file
User, Date, Email, Administrator, Comments
a, 20201719, a@a.com, Yes, 3
b, 20182817, b@b.com, No, 4
c, 20191618, , No, 4
d, 20190126, , No, 2

另請參閱使用 awk 有效解析 CSV 的最可靠方法是什么? 如果您需要使用比問題中更復雜的 CSV 文件。

您可以使用 Miller ( https://github.com/johnkerl/miller ) 及其remove-empty-columns動詞。

從...開始

+------+----------+---------+---------------+-------+----------+
| User | Date     | Email   | Administrator | Posts | Comments |
+------+----------+---------+---------------+-------+----------+
| a    | 20201719 | a@a.com | Yes           | -     | 3        |
| b    | 20182817 | b@b.com | No            | -     | 4        |
| c    | 20191618 | -       | No            | -     | 4        |
| d    | 20190126 | -       | No            | -     | 2        |
+------+----------+---------+---------------+-------+----------+

和跑步

mlr --csv remove-empty-columns input.csv >output.csv

你將會有

+------+----------+---------+---------------+----------+
| User | Date     | Email   | Administrator | Comments |
+------+----------+---------+---------------+----------+
| a    | 20201719 | a@a.com | Yes           | 3        |
| b    | 20182817 | b@b.com | No            | 4        |
| c    | 20191618 | -       | No            | 4        |
| d    | 20190126 | -       | No            | 2        |
+------+----------+---------+---------------+----------+

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM