0

次のような名前のプレーン テキスト ファイルがたくさんあります: file1.txt、file2.txt、...、file14.txt、... すべてを適切な順序で 1 つの .txt ファイルに連結したいと考えています。プログラムでこれを行うにはどうすればよいですか? コマンドウィンドウで実行されているバッチファイル? または、Windows コンソール アプリを作成しますか?

いずれにせよ、コードをいただけますか?ありがとう。

より詳しい情報:

  • 多数のファイル。このレポートを作成するたびに、100 以上。

  • dir はファイルを適切な順序で提供しません。たとえば、file10.txt は file2.txt の前に表示されます。それが私の強調の理由です。ファイル名のプレフィックスに連結された 1 から n までの for i が最適なようです。しかし、これをバッチモードで行う方法、または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();
        }


    }
}
4

7 に答える 7

2

Windowsを使用している場合は、cygwinをインストールして、bashシェルを使用できるようにします。

for i in {1..N}; do cat $ {1} .txt >> all.txt; 終わり

Nはファイルの数です。ファイルはすべてall.txtに連結されます。

于 2011-09-02T05:13:07.463 に答える
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
于 2011-07-23T05:39:25.437 に答える
1

最小限の時間を投資したい場合、これはうまくいくはずです。完全に自動化されたプロセスの場合、ファイルの数を把握する必要があります (これはそれほど難しくありませんが、ここでは省略します)。しかし、わずか 20 個のレポートの場合、これでおそらくうまくいくはずです。

さらに、バッチ ファイルのプロセスは最適ではありません。実際、それは恐ろしいことです。(  !)だと思います。バッチ ファイルの下にあるバージョンを使用する方がおそらくはるかに優れています。

バッチ ファイルとして:

@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あなたが持っている最高の接尾辞に置き換えるだけです。

于 2011-07-23T06:52:11.007 に答える
1

これは、次の Windows PowerShell ワンライナーで実行できます (読みやすくするために、ここでは 4 行に広げています)。

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

Get-ChildItemファイル名を取得しますが、それらは間違った順序になります (アルファベット順ではなく ASCII 順でソートされます)。

コマンドレットを使用して、Sort-Objectファイル名を比較する前にファイル名の数字をパディングして、指定したとおりにファイル名を並べ替えます。

gcGet-Contentすべての入力ファイルの内容を読み取る のエイリアスです。

scSet-Contentは、指定されたファイルに結果を書き込む のエイリアスです。


PowerShell を使用できない/使用しない場合に備えて、C# を使用した別の方法を次に示します。

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 エクスプローラーがファイル名の並べ替えに使用するものです)。

于 2011-07-23T06:05:06.430 に答える
1

いくつかの可能性があります。コマンドラインでa を実行するdirと、必要な順序で表示されます。物事は非常に簡単です。次のようなことができます。

copy file*.txt destination.txt

これには、いくつかの小さな副作用があります。最初に遭遇したファイルの読み取りを停止し、ファイルの末尾にcontrol-Za を追加します。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(など) は、コピーするファイルであり、コピーする順序でリストされています (そして、明らかに、destination.txtすべてをまとめた結果に付けたい名前です。別の方法として、のように 1 つのコマンド ラインですべてを一覧表示できますcopy a.txt+b.txt+c.txt destination.txt

于 2011-07-23T05:10:02.720 に答える
0

コマンドプロンプトで、実行できます、 type *.txt > destination.txt

注: これにより、サブディレクトリの下のテキスト ファイルも連結されます。

于 2015-11-18T09:19:59.720 に答える
-1

私は、split & concat という 1 つの非常に便利なプログラムを覚えています。Mac OS Xの場合...別のOSバージョンがあるかどうかわかりません...うまくいきます!http://loekjehe.home.xs4all.nl/Split&Concat/

于 2011-07-23T05:14:54.547 に答える