无法获取 csv 文件的准确记录数

无法获取 csv 文件的准确记录数

我有一个 .csv 文件,其中有一些值被格式化为带有换行符或有时是项目符号的段落。

"STAT","ID","DESC"
"UPD", "1", "Updated"
"CHG", "2", "Changed"
"UPD", "3", "Updated.
Might have to update again"
"UPD", "4", "Updated.

 - once 
 - twice
 - thrice
"
"DEL", "5", "unknown"
"DEL", "6", "Deleted
Need to restore"

我需要计算记录数,使用 awk 如下,因为我知道第二列是唯一的 ID,但返回的结果比我拥有的多。上面的文本当然是假的,因为我不允许分享原件,但我尽可能地反映了实际情况。

 awk  '{print $2}' FS=","  sample.csv | wc -l 

我甚至使用 awk '{print $1}' 打印出第一列来检查第一列的值,但输出显示段落中新行的起始部分。

如果需要任何其他信息,请告诉我,我会更新问题。

答案1

一种方法awk

awk -v RS=$'"\n"' 'END {print NR}' sample.csv
  • RS=$'"\n"'设置R记录年代eparator(默认情况下为换行符)替换为三个字符的字符串", newline, "。此语法可能仅在 中有效bash。这将导致您的文件分解为以下记录:

    1:"STAT","ID","DESC

    2:UPD", "1", "Updated

    3:CHG", "2", "Changed

    4:UPD", "3", "Updated.
        Might have to update again

    5:UPD", "4", "Updated.
       
        - once
        - twice
        - thrice
       

    6:DEL", "5", "unknown

    7:DEL", "6", "Deleted
        Need to restore"

    这假设文件中没有尾随空格。 

  • 'END {print NR}'读取文件直到结束,然后打印记录号 - 换句话说,记录的数量。

文本文件通常被认为是由一系列行组成,由换行符或字符序列分隔。并且,通常,文本文件中的“记录”被视为一行。但awk允许您指定除换行符之外的记录分隔符。由于 quote-newline-quote 字符串出现在每对连续的记录在您的文件中,将其指定为记录分隔符会将文件分成(非常接近)您想要的记录。

但记录分隔符就像两个房间之间的墙——它不是任何一个房间的一部分。在正常awk处理中,您会看到以线条形式出现的记录没有换行符 – 它们会被删除。同样,在我的回答中,引号-换行符-引号序列也会被删除。但是,由于第一条记录之前或最后一条记录之后没有记录分隔符,因此不会删除第一个和最后一个引号字符。

如果您想要逐条处理文件,此解决方案可能不够好,因为第一条记录和最后一条记录的处理方式不同。我(在某种程度上)同意 Glenn 的建议,即对于任何严肃的工作,您都应该使用“适当的 CSV 解析器”。

答案2

我强烈建议选择一种具有适当 CSV 解析器的语言。我喜欢 ruby​​,它非常简洁:

ruby -rcsv -e 'a = CSV.read(ARGV[0], :col_sep => ", "); puts a.length' file
7

我必须修改标题行中的列分隔符以添加空格。

答案3

以下是在 Python 中实现此目的的另一种方法:

python -c "import csv; import sys; print(sum(1 for line in csv.reader(open(sys.argv[1]))))" your-file.csv

灵感来自这个答案

相关内容