繁体   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