如何根据文本字符串将 CSV 文件拆分为多个文件?

如何根据文本字符串将 CSV 文件拆分为多个文件?

我有多个文本文件(CSV),其结构类似于此:

funkiana,23.55,-99.866
funkiana,24.634,-98.701
funkiana,24.717,-98.901
geminiflora,22.25,-104.6166667
geminiflora,21.21666667,-104.65
horrida,19.633,-97.367
horrida,23.61666667,-102.575
horrida,22.158,-100.979
horrida,19.506,-97.433
horrida,17,-97.56667
horrida,19.485,-97.263
horrida,19.017,-99.133
horrida,19.017,-99.15
horrida,18.91,-99.23
horrida,17.82167,-100.26333
horrida,19.507,-97.438
inaequidens,19.399,-99.314
inaequidens,23.58333,-105.8833
inaequidens,19.767,-103.7
inaequidens,20.787,-103.848

如您所见,有三个字段(物种、纬度和经度)。现在,我想将每个 CSV 文件拆分为不同的 CSV 文件,仅包含每个物种的数据。换句话说,我想要一个文件包含所有出现的funkiana(带纬度/经度),另一个文件包含geminiflora(带纬度/经度),依此类推。

有什么想法可以实现这一点吗?也许使用脚本或 Excel 宏?

答案1

我能想到的最快的方法是使用 PowerShell

$fullpath = "D:\myFolder\input.csv"

$path = Split-Path $fullpath -parent
$data = Import-CSV -Delimiter "," -Path $fullpath -Header species,latitude,longitude  

foreach ($group in $data | Group species){        
    $data | Where-Object {$_.species -eq $group.name} | 
        ConvertTo-Csv -NoTypeInformation | 
        foreach {$_.Replace('"','')} | 
        Out-File "$path\$($group.name).csv"     
}
  1. 将代码粘贴到新的文本文件中并将其另存为例如MySplitMacro.ps1
  2. 编辑第一行并更改$fullpath为所需的 CSV 路径
  3. 右键单击该.ps1文件,然后单击使用 PowerShell 运行

以您的初始示例作为输入,脚本将在与输入文件相同的位置创建 4 个新的 CSV 文件。按第一列过滤时,每个 CSV 将包含一组条目。

生成的示例文件夹
在此处输入图片描述

一个结果示例文件
在此处输入图片描述

调整

  • 改变物种设置$data | Group species要过滤的列
  • -Delimiter ","如果您的输入文件有不同的分隔符(如制表符“`t”或分号“;”),请进行更改
  • 更改-Header species,latitude,longitude您的列名称。正确排序
  • $path\$($group.name).csv如果需要不同的输出路径,请进行更改
  • -eq $group.name除了过滤结果之外,您还可以使用-like *$group.name*通配符比较或-match '[A-Z]$group.name'RegEx 比较

使用的资源

答案2

您所要求的通常称为“控制中断”过程。有一个“控制”值。在您的情况下,它是物种。当它改变值或“中断”时,我们想要做某事。在您的情况下,您想要写出一个新文件。

有很多方法可以解决您的问题。我通常会使用脚本语言而不是 Excel 来解决它。

如果您有兴趣了解如何编写这样的程序/脚本,此链接将为您提供指导: http://www.unix.com/tips-and-tutorials/209439-how-do-control-break-algorithm.html

如果您使用的是 Windows 平台并且不介意使用编程语言,则可以使用 LinqPad (http://www.linqpad.net/) 有一个免费版本和以下 C# 程序(请确保在 LinqPad 语言下拉菜单中选择“C# 程序”):

void Main()
{
    var path = @"c:\sourceGit\speciesLatLon.txt";
    var inputLines = File.ReadAllLines(path);

    // Holds all the lines to be added to each output file
    var linesForCurrentSpeciesFile = new List<string>(); 

    // Read first row
    int i = 0;
    var currentSpecies = GetSpecies(inputLines[i]);

    // initialize hold value
    var holdValue = currentSpecies;

    // Initialize output values
    linesForCurrentSpeciesFile.Add(inputLines[i]);

    // Read next value
    i++;

    while( i < inputLines.Length )
    {
        currentSpecies = GetSpecies(inputLines[i]);
        if (currentSpecies !=  holdValue)
        {
            // output current file
            WriteSpeciesFile(holdValue, linesForCurrentSpeciesFile);

            // Initialize new output file by clearing out the previous
            linesForCurrentSpeciesFile.Clear();

            // update hold value with the value just examined.
            holdValue = currentSpecies;
        }
        // Add the current line to the output file
        linesForCurrentSpeciesFile.Add(inputLines[i]);
        i++;
    }
    // Write the output file because last row is equal to a break in the sequence
    WriteSpeciesFile(currentSpecies, linesForCurrentSpeciesFile);
}

// Define other methods and classes here
public string GetSpecies(string line)
{
    // return the first value of the input line
    return line.Split(new char[] {','})[0];
}

public void WriteSpeciesFile(string species, List<string> content)
{
    File.WriteAllLines(string.Format(@"C:\sourceGit\{0}.csv", species), content.ToArray());
}

答案3

一个简单的 csv 搜索应用程序(如 CsvFileSearch)就可以做到这一点,而无需复杂化。它将搜索多个文件并将结果保存到另一个文件中。

相关内容