连接纯文本文件的最佳方法?

时间:2011-07-23 05:02:53

标签: .net windows command-line windows-console

我有一大堆纯文本文件,命名如下:file1.txt,file2.txt,...,file14.txt,... 我想将所有这些IN PROPER ORDER连接到一个.txt文件。 我该如何以编程方式执行此操作? 批处理文件在命令窗口中运行? 或者编写一个Windows控制台应用程序?

无论哪种方式,我可以拥有代码吗?感谢。

更多信息:

  • 大量文件。每次我报告时都会有一百个或更多。

  • dir不会按正确的顺序提供文件:例如file2.txt出现在file2.txt之前,这就是我强调的原因。似乎对于i从1到n连接到文件名前缀是最好的。但我不知道如何在批处理模式下执行此操作或从Windows程序执行命令。

我倾向于使用Windows控制台应用程序。这样的事情会起作用吗?

class Program
{
    static void Main(string[] args)
    {
        string strCmdLine;
        System.Diagnostics.Process process1;
        process1 = new System.Diagnostics.Process();


        Int16 n = Convert.ToInt16(args[1]);
        int i;
        for (i = 1; i < n; i++)
        {
            strCmdLine = "/C copy more work here " + args[0] + i.ToString();
            System.Diagnostics.Process.Start("CMD.exe", strCmdLine);
            process1.Close();
        }


    }
}

7 个答案:

答案 0 :(得分:2)

不是最有效的代码,但您应该能够理解:

        Dim files As String()
    Dim tempFile As String
    Dim orderedFiles As New Dictionary(Of Int32, String)
    Dim fileNumber As Int32
    Dim filePos As Int32
    Dim dotTxtPos As Int32
    Dim fileData As String
    Const CONST_DEST_FILE As String = "c:\tempfiles\destination.txt"

    files = System.IO.Directory.GetFiles("c:\tempfiles", "file*.txt")

    For Each tempFile In files
        If tempFile.ToLower.Contains("\file") = False Or tempFile.ToLower.Contains(".txt") = False Then
            Continue For
        End If

        filePos = tempFile.ToLower.IndexOf("\file") + 5
        dotTxtPos = tempFile.ToLower.IndexOf(".txt", filePos)
        If Int32.TryParse(tempFile.ToLower.Substring(filePos, dotTxtPos - filePos), fileNumber) = True Then
            orderedFiles.Add(fileNumber, tempFile)
        End If
    Next

    If System.IO.File.Exists(CONST_DEST_FILE) = True Then
        System.IO.File.Delete(CONST_DEST_FILE)
    End If

    fileNumber = 0
    Do While orderedFiles.Count > 0
        fileNumber += 1
        If orderedFiles.ContainsKey(fileNumber) = True Then
            tempFile = orderedFiles(fileNumber)
            fileData = System.IO.File.ReadAllText(tempFile)
            System.IO.File.AppendAllText(CONST_DEST_FILE, fileData)
            orderedFiles.Remove(fileNumber)
        End If
    Loop

答案 1 :(得分:2)

如果你在Windows上,安装cygwin以便你可以拥有一个bash shell,然后:

代表{1..N}中的i;做猫$ {1} .txt&gt;&gt; all.txt;完成

其中N是您拥有的文件数,这些文件将全部连接在all.txt

答案 2 :(得分:1)

你有几种可能性。如果你在命令行中执行dir,并且它们按照你想要的顺序出现,那么事情就很简单了 - 你可以这样做:

copy file*.txt destination.txt

这会产生一些轻微的副作用 - 它会在遇到的第一个control-Z停止读取任何给定的文件,它会在文件的末尾附加一个control-Z 。如果您不希望这些发生,可以添加/b

copy /b file*.txt destination.txt

如果“目录”顺序不是您想要的顺序,那么您可以执行以下操作:

for %c in (a.txt b.txt c.txt) copy destination.txt+%c

其中a.txtb.txtc.txt(等)是您要复制的文件,按照您希望复制的顺序列出(显然,{{1}是你要将它们放在一起的结果的名称。或者,你可以在一个命令行中列出它们,如destination.txt

答案 3 :(得分:1)

这可以使用以下Windows PowerShell一行(在这里分为四行以便于阅读)来完成:

Get-ChildItem -Filter "*.txt" | 
    Sort-Object { [regex]::Replace($_, '\d+', { $args[0].Value.PadLeft(20) }) } | 
    gc | 
    sc result.txt

Get-ChildItem检索文件名,但它们的顺序错误(按字母顺序排序,而不是按字母顺序排序)。

Sort-Object cmdlet用于按照您指定的方式对文件名进行排序,方法是在比较名称之前填写文件名中的数字。

gcGet-Content的别名,它读取所有输入文件的内容。

scSet-Content的别名,它将结果写入指定的文件。


以下是使用C#的替代方法,以防您不能/不会使用PowerShell:

static class Program
{
    [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
    static extern int StrCmpLogicalW(string s1, string s2);

    static void Main()
    {
        string[] files = Directory.GetFiles(@"C:\Path\To\Files", "*.txt");
        Array.Sort(files, StrCmpLogicalW);
        File.WriteAllLines("result.txt", files.SelectMany(file => File.ReadLines(file)));
    }
}

这使用StrCmpLogicalW函数以正确的顺序获取文件名(该函数实际上是Windows资源管理器用于对文件名进行排序的函数)。

答案 4 :(得分:1)

如果您愿意投入最少的时间,这应该会很好。对于一个强制自动化的过程,你需要弄清楚文件的数量(这不是太难,我从这里省略了)。但是对于仅有20份报告,这可能会很好。

此外,批处理文件中的过程不是最佳的。事实上,这太可怕了。我认为它是 O n !)。使用批处理文件下面的版本可能要好得多。

作为批处理文件:

@echo off
if not "%~1"=="" goto begin
echo Usage: %~n1 ^<N^>
echo where ^<N^> is the highest number that occurs in the file name.
goto :eof

:begin
set N=%~1
rem create empty file
copy nul temp.txt
rem just loop from 1 to N
for /l %%x in (1,1,%N%) do call :concat %%x
rename temp.txt result.txt
goto :eof

:concat
  copy temp.txt+file%1.txt temp2.txt
  move /y temp2.txt temp.txt
goto :eof

未经测试,但它非常简单,所以我怀疑其中存在太多错误。

或者,我只是认为以下更容易(在命令行上):

(for /l %x in (1,1,N) do type file%x.txt) > result.txt

只需将N替换为您拥有的最高后缀。

答案 5 :(得分:0)

在命令提示符下,您可以执行, type *.txt > destination.txt

  

注意:这也会连接子目录

下的文本文件

答案 6 :(得分:-1)

我记得一个非常有用的程序:split&amp; CONCAT。对于mac os x ...不知道是否有其他操作系统版本...做的工作! http://loekjehe.home.xs4all.nl/Split&Concat/