【问题标题】:A Windows script to merge three csv file columns into one single column将三个 csv 文件列合并为一列的 Windows 脚本
【发布时间】:2013-03-13 05:10:57
【问题描述】:

我可以在 excel 中执行此操作,例如使用 =CONCATENATE 函数将多个列合并为一列。但我想做的是将同一文件夹内的 3 个不同 csv 文件中的列合并为一列。我想通过批处理脚本运行它,所以像 VBScript 这样的 CMD 复制命令似乎不起作用。

这是文件结构:

文件1.csv

  • 第 1 列:www.domain.com/
  • 第 2 栏:www.nwdomain.com/
  • 第 3 列:www.stackdomain.com/
  • 第 4 列:www.example-domain.com/

文件 2.csv

  • 第 1 列:关于
  • 第 2 栏:联系人
  • 第 3 列:索引
  • 第 4 列:常见问题解答

文件 3.csv

  • 第 1 列:.html
  • 第 2 列:.html
  • 第 3 列:.html
  • 第 4 列:.html

输出文件的结果:

  • 列 1:www.domain.com/about.html

  • 第 2 列:www.nwdomain.com/contact.html

  • 列 3:www.stackdomain.com/index.html

  • 第 4 列:www.example-domain.com/faq.html

感谢您的帮助。

【问题讨论】:

    标签: csv excel vbscript batch-file vba


    【解决方案1】:
    @ECHO OFF
    SETLOCAL
    ::
    (
    FOR /f "tokens=1*delims=:" %%a IN ('findstr /n /r "." ^<csv1.csv') DO (
     FOR /f "tokens=1*delims=:" %%c IN ('findstr /n /r "." ^<csv2.csv') DO ( 
      IF %%a==%%c FOR /f "tokens=1*delims=:" %%e IN ('findstr /n /r "." ^<csv3.csv') DO (
       IF %%a==%%e (
        FOR /f "tokens=1-4delims=," %%m IN ("%%b") DO (
         FOR /f "tokens=1-4delims=," %%r IN ("%%d") DO (
          FOR /f "tokens=1-4delims=," %%w IN ("%%f") DO (
           ECHO.%%m%%r%%w,%%n%%s%%x,%%o%%t%%y,%%p%%u%%z
          )
         )
        )
       )   
      )
     )
    )
    )>new.csv
    

    应该可以。

    它的作用是,

    1. 对于 file1,FINDSTR “输出”任何包含任何字符 (/r ".") 的行,其前面是行号和冒号 (/n)。此“输出”由FOR /f 读取并解析为 2 个标记,由冒号分隔(tokens=1* 表示“第一个标记;该行的所有其余部分”),效果是将行号放入%%a 和其余行,即从原始 .csv%%b 的行
    2. 对于csv1的每一行重复csv2,这次将行号放入%%c,将行放入%%d
    3. 仅当行号匹配时,对csv3 重复%%e 中的数字和%%f 中的文本
    4. 如果最后一个文件中的行号匹配,则解析%%b%%d%%f 中的行文本 - 这次选择用逗号分隔的四列。这些数据出现在%%m..%%p%%r..%%u%%w..%%z 中,然后我们要做的就是对接适当的部分并插入逗号。李>

    完成!


    源和测试结果,包括运行时间(5 行)
    start:21:45:40.87
    end  :21:45:41.09
    
    csv1.csv =========
    www.domain.com/,www.nwdomain.com/,www.stackdomain.com/,www.example-domain.com/
    www.domain.com/,www.nwdomain.com/,www.stackdomain.com/,www.example-domain.com/
    www.domain.com/,www.nwdomain.com/,www.stackdomain.com/,www.example-domain.com/
    www.domain.com/,www.nwdomain.com/,www.stackdomain.com/,www.example-domain.com/
    www.domain.com/,www.nwdomain.com/,www.stackdomain.com/,www.example-domain.com/
    csv2.csv =========
    about,contact,index,faq
    about,contact,index,faq
    about,contact,index,faq
    about,contact,index,faq
    about,contact,index,faq
    csv3.csv =========
    .html,.html,.html,.html
    .html,.html,.html,.html
    .html,.html,.html,.html
    .html,.html,.html,.html
    .html,.html,.html,.html
    new.csv =========
    www.domain.com/about.html,www.nwdomain.com/contact.html,www.stackdomain.com/index.html,www.example-domain.com/faq.html
    www.domain.com/about.html,www.nwdomain.com/contact.html,www.stackdomain.com/index.html,www.example-domain.com/faq.html
    www.domain.com/about.html,www.nwdomain.com/contact.html,www.stackdomain.com/index.html,www.example-domain.com/faq.html
    www.domain.com/about.html,www.nwdomain.com/contact.html,www.stackdomain.com/index.html,www.example-domain.com/faq.html
    www.domain.com/about.html,www.nwdomain.com/contact.html,www.stackdomain.com/index.html,www.example-domain.com/faq.html
    =============
    

    【讨论】:

    • 这在 5 个字符串匹配时似乎很慢。
    • 如果你的意思是你只有5行数据,那么我已经发布了我的测试数据和运行结果。我做了一个小的编辑(在ECHO.%%m%%r... 行上,w 之前有 4 个% - 这应该是 2 [在输出中添加一个虚假的%])但那会对时间没有影响。您只使用 5 行数据吗?如果是这样,您可以发布它们(或经过编辑的版本)。显然,不要发布数百行...如您所见,我的运行时间是 0.22 秒,我不会将其描述为特别慢。 OTOH,我让CMD 决定不负责任地花费很长时间并需要一个新的 CMD 实例。
    【解决方案2】:

    在 VBScript 中:

    Const delim = ","
    
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Set f1 = fso.OpenTextFile("File1.csv")
    Set f2 = fso.OpenTextFile("File2.csv")
    Set f3 = fso.OpenTextFile("File3.csv")
    
    Do Until f1.AtEndOfStream Or f2.AtEndOfStream Or f3.AtEndOfStream
      a1 = Split(f1.ReadLine, delim)
      a2 = Split(f2.ReadLine, delim)
      a3 = Split(f3.ReadLine, delim)
    
      n = Min(UBound(a1), UBound(a2), UBound(a3))
      Dim aout(n)
    
      For i = 0 To n
        aout(i) = a1(i) & a2(i) & a3(i)
      Next
    
      WScript.StdOut.WriteLine Join(aout, delim)
    Loop
    
    f1.Close
    f2.Close
    f3.Close
    
    Function Min(a, b, c)
      If a<=b Then
        If c<a Then
          Min = c
        Else
          Min = a
        End If
      Else
        If c<b Then
          Min = c
        Else
          Min = b
        End If
      End If
    End Function
    

    【讨论】:

      【解决方案3】:

      虽然不是真正的编程,但一种快速而肮脏的方法是在 Excel 中打开所有文件,创建一个新的 XLSXLSX 文件,然后在新创建的文件的第一个单元格中使用这个公式:

      =[File1.csv]File1!A1&[File2.csv]File2!A1&[File3.csv]File3!A1
      

      File1.csvFile2.csvFile3.csv 是您的 CSV 文件。 然后拖动列/行以应用公式。

      【讨论】:

        猜你喜欢
        • 2018-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-17
        • 1970-01-01
        • 2021-12-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多