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

发布于 2024-11-26 11:13:08 字数 937 浏览 1 评论 0原文

我有一大堆纯文本文件,名称如下:file1.txt、file2.txt、...、file14.txt、... 我想将它们全部按正确的顺序连接到一个 .txt 文件。 我应该如何以编程方式执行此操作? 在命令窗口中运行批处理文件? 或者编写一个 Windows 控制台应用程序?

不管怎样,我可以有代码吗?谢谢。

更多信息:

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

  • dir 不会以正确的顺序给出文件:例如,file10.txt 出现在 file2.txt 之前,这就是我强调的原因。看来 for 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();
        }


    }
}

I have a whole bunch of plain text files named as follows: file1.txt, file2.txt, ..., file14.txt, ...
I want to concatenate all of them IN PROPER ORDER to one .txt file.
How should I do this programmatically?
Batch file running in a command window?
Or write a Windows console app?

Either way, could I have the code? Thanks.

More info:

  • large number of files. A hundred or more each time I do this report.

  • dir won't give the files in proper sequence: file10.txt appears before file2.txt for example, that's why my emphasis. It seems a for i from 1 to n concatenated to the file name prefix is the best. But I don't know how to do this either in batch mode or to execute command from Windows program.

I am leaning towards doing a Windows console app. Will something like this work?

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();
        }


    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

甜扑 2024-12-03 11:13:08

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

        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

Not the most efficient code, but you should be able to get the idea:

        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
风筝在阴天搁浅。 2024-12-03 11:13:08

如果您使用的是 Windows,请安装 cygwin,以便您可以拥有 bash shell,然后:

for i in {1..N} ;做猫 ${1}.txt >>所有.txt;完成

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

If you are on windows, install cygwin so you can have a bash shell, then:

for i in {1..N} ; do cat ${1}.txt >> all.txt ; done

Where N is the number of files you have, The files will all be concatenated in all.txt

孤独陪着我 2024-12-03 11:13:08

如果您愿意投入最少的时间,这应该会很有效。对于完全自动化的过程,您需要计算出文件的数量(这并不难,但我在这里省略了)。但对于只有 20 份报告来说,这应该没问题。

此外,批处理文件中的过程并不是最佳的。事实上,这很可怕。我认为是On!)。使用批处理文件下面的版本可能会更好。

作为批处理文件:

@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 替换为您拥有的最高后缀。

This should work well if you're willing to invest a minimum of time. For a compeltely automated process you would need to figure out the number of files (which isn't too hard, bu I omitted from here). But for just 20 reports this should probably do fine.

Furthermore, the process in the batch file isn't optimal. In fact, it's horrible. I think it's O( n !). It's probably much better to use the version below the batch file.

As a batch file:

@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

Untested, but it's pretty straightforward, so I doubt there's too many bugs in it.

Alternatively, I just thought that the following would work even easier (on the command line):

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

Just replace N with the highest suffix you have.

你穿错了嫁妆 2024-12-03 11:13:08

你有几种可能性。如果您在命令行执行 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

where a .txtb.txtc.txt(等)是您要复制的文件,按照您希望复制的顺序列出(并且,显然,destination.txt 是您想要的名称给出将它们全部放在一起的结果。或者,您可以在一个命令行中将它们全部列出,例如copy a.txt+b.txt+c.txt destination.txt

You have a couple of possibilities. If you do a dir at the command line, and they show up in the order you want them, things are pretty easy -- you can do something like:

copy file*.txt destination.txt

That will have a couple minor side-effects -- it'll stop reading any given file at the first control-Z it encounters, and it'll append a control-Z to the end of the file. If you don't want those to happen, you can add a /b:

copy /b file*.txt destination.txt

If the "directory" order isn't the order you want, then you can do something like:

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

where a.txt, b.txt, c.txt (etc.) are the files you want copied, listed in the order you want them copied (and, obviously enough, destination.txt is the name you want to give to the result where you've put them all together. Alternatively, you can list them all in one command line like copy a.txt+b.txt+c.txt destination.txt.

挽手叙旧 2024-12-03 11:13:08

这可以通过以下 Windows PowerShell 一行代码来完成(为了便于阅读,这里分为四行):

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

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

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 资源管理器的函数)用于对文件名进行排序)。

This can be done with the following Windows PowerShell one liner (spread over four lines here for readability):

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

Get-ChildItem retrieves the file names, but they will be in the wrong order (sorted ASCIIbetically rather than alphabetically).

The Sort-Object cmdlet is used to sort the file names as you specified, by padding out the numbers in the file name before comparing the names.

gc is an alias for Get-Content, which reads the contents of all the input files.

sc is an alias for Set-Content, which writes the result to the specified file.


Here is an alternate approach using C#, in case you can't/won't use 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)));
    }
}

This uses the StrCmpLogicalW function to get the file names in the right order (that function is actually what Windows Explorer uses to sort file names).

以往的大感动 2024-12-03 11:13:08

在命令提示符下,您可以执行,
类型 *.txt >目的地.txt

注意:这也会连接子目录下的文本文件

In command prompt, you can execute,
type *.txt > destination.txt

Note: This also concatenates text files under sub-directories

嘿咻 2024-12-03 11:13:08

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

i remember of a single very useful program: split & concat. for mac os x... don't know if had another os versions... does the work! http://loekjehe.home.xs4all.nl/Split&Concat/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文