3

我可以在 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

  • Column1:关于
  • 栏目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

谢谢你的帮助。

4

3 回答 3

2
@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. FOR EACH LINE 的csv1重复 for csv2,这次将行号放入%%c, line in%%d
  3. 仅当行号匹配时,csv3使用 in 中的数字%%e和 in 中的文本重复 for%%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
=============
于 2013-03-23T11:37:33.933 回答
1

在 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
于 2013-03-23T15:40:16.130 回答
0

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

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

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

于 2013-03-23T11:14:24.160 回答