【问题标题】:How to write script to read many CSV filename and data and write into another CSV file?如何编写脚本来读取许多 CSV 文件名和数据并写入另一个 CSV 文件?
【发布时间】:2021-04-05 11:31:53
【问题描述】:

我有很多 CSV 文件名,需要将文件中的所有文件名和数据写入另一个 CSV 文件。

示例:

文件1:less bonding_err_bond0-if_eth2-d.rrd.csv

1617613500,0.0000000000e+00

文件 2:less bonding_err_bond0-if_eth3-d.rrd.csv

1617613500,0.0000000000e+00

最终输出结果

最终文件:less bonding.csv

bonding_err_bond0-if_eth2-d.rrd,bonding_err_bond0-if_eth3-d.rrd.csv
0.0000000000e+00,0.0000000000e+00

注意:脚本可以是python或bash脚本

【问题讨论】:

    标签: python bash shell csv script


    【解决方案1】:

    Pandas Python 库非常适合处理 CSV。

    import os
    import pandas as pd
    import re
    
    out_file_name = './less bonding.csv'
    
    # Create a Pandas DataFrame
    output = pd.DataFrame()
    
    # Remove any output files we might've made previously
    if os.path.isfile(out_file_name):
        os.remove(out_file_name)
    
    # Get all the files in the current dir
    file_names = os.listdir()
    
    # Loop through our file_names
    for file_name in file_names:
    
        # Regex check it's a .csv file
        csv = re.match(r'^.+\.csv$', file_name)
        if(csv != None):
    
            # Read our csv into a DataFrame
            # To preserve our data rather than it be converted to floats, use dtype=str
            data = pd.read_csv(file_name, header=None, dtype=str)
    
            # Put column 1 of csv into column [file_name] of our output DataFrame
            output[file_name] = data[1]
    
    # Remove the index (first column) - we don't need it
    output.set_index(output.columns[0], inplace=True)
    
    # Output it as a csv
    output.to_csv(out_file_name)
    
    

    这是输出:

    less bonding_err_bond0-if_eth2-d.rrd.csv,less bonding_err_bond0-if_eth3-d.rrd.csv
    0.0000000000e+00,0.0000000000e+00
    

    【讨论】:

      【解决方案2】:

      所以基本上你想要一个带有文件名和一个数据字符串的表头的表?这是一个可以帮助你的sn-p

      #!/bin/bash
      HEADER=''
      DATA=''
      while IFS= read -r -d '' CSV
      do
        HEADER="${HEADER}$(basename "$CSV"),"
        DATA="${DATA}$(cut -d "," -f 2 "$CSV"),"
      done <   <(find ./ -name "*.csv" -type f -print0)
      echo "${HEADER%,}"
      echo "${DATA%,}"
      

      首先我们初始化两个空变量,HEADER 将包含我们所有的文件名,DATA 包含每个文件的第二个字段,用, 符号分隔。

      之后我们有一个 while 循环,它可能看起来很复杂,但这里解释了其原因:https://github.com/koalaman/shellcheck/wiki/SC2044

      TLDR 版本是我们要处理所有可能破坏 for 循环的异常字符。

      在循环中,我们将包含在CSV 变量中的文件名附加到HEADER 变量中。 basename 只给我们文件名部分,没有文件夹。如果你不需要.csv 扩展,你可以在那里使用basename -s .csv "$CSV" 作为命令。

      DATA 以相同的方式处理,但我们将文件内容按, 拆分并仅打印第二个字段。

      在形成两个字符串后,我们用删除的尾随逗号来回显它们,这种技术称为 bash 参数替换,请查看 https://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html 了解更多信息。

      此脚本将处理当前目录及其子目录中的所有 csv 文件。

      要从中创建文件,只需将其输出重定向到文件,即将此脚本另存为 merge_csv.sh 并运行

      bash merge_csv.sh > bonding.csv
      

      测试:

      生成5个内容相似的文件:

      for i in $(seq 1 5); do echo "0.0000000000e+00,$i.0000000000e+00" > "$i.csv"; done
      

      在文件夹中运行此脚本会导致:

      1,2,3,4,5
      1.0000000000e+00,2.0000000000e+00,3.0000000000e+00,4.0000000000e+00,5.0000000000e+00
      

      【讨论】:

        【解决方案3】:

        顺便说一下 Pandas,Python 库非常有用。

        这是一个例子:

        from pathlib import Path
        import csv, os
        import pandas as pd
        
        def finalFile(fname):
            
            output = pd.DataFrame()
        
            file_names = os.listdir()
        
            for file_name in file_names:
                if file_name.startswith(fname):
                    data = pd.read_csv(file_name, header=None, dtype=str)
                    output[file_name.rsplit('.', 4)[2]] = data[1]
        
            output.set_index(output.columns[0], inplace=True)
            output.to_csv(fname.rsplit('.', 2)[2] + ".csv")
        
        
        finalFile('xxx.test.test-bonding')
        

        最终结果

        test-bonding_err_bond0-if_eth3-d,test-bonding_err_bond0-if_eth2-d
        0.0000000000e+00,0.0000000000e+00
        

        【讨论】:

          猜你喜欢
          • 2011-02-05
          • 2019-10-05
          • 2017-05-17
          • 2015-05-23
          • 1970-01-01
          • 1970-01-01
          • 2011-03-09
          • 1970-01-01
          • 2023-01-10
          相关资源
          最近更新 更多