【问题标题】:Batch file to sort txt after appending from other txt从其他txt追加后对txt进行排序的批处理文件
【发布时间】:2023-03-29 10:31:02
【问题描述】:

我想要一个批处理文件,我可以将一个文本文件拖到上面(最好是一次多个文本文件),它将逐行读取每个文本文件并将每一行添加到指定的目标文本文件中。目标文本文件将不包含任何重复的行,并将按字母顺序排序。源文件永远不会包含同一行两次,但可能包含非字母数字字符,例如:{ - : _ ~ !

例子:

a.txt:

apple
banana
garbage carrot
{Elmer Fudd}

b.txt

1 tequila
2 tequila
3 tequila
garbage carrot
{Bugs Bunny}

destination.txt 之前:

{daffy duck}
floor

将a.txt和b.txt拖到批处理文件后的destination.txt:

{Bugs Bunny}
{daffy duck}
{Elmer Fudd}
1 tequila
2 tequila
3 tequila
apple
banana
floor
garbage carrot

我已经开始了:

@echo off
setlocal disabledelayedexpansion
set "sourcefile=%~1"
echo "%sourcefile%" > temp.txt
for /f "delims=;" %%F in (%sourcefile%) do (
    echo %%F>>temp.txt
)

del /q destination.txt
ren temp.txt destination.txt

它将文件复制到一个临时文件中,但我不知道如何对其进行排序。排序命令对我不起作用,它只是挂起程序。感谢所有帮助。谢谢!

【问题讨论】:

  • 按字母顺序批量处理特殊字符将非常困难。
  • 我知道困难所在。我目前陷入困境,我什至无法将非特殊字符复制到临时文件中。它一直打开最初拖动的文件而不是读取它:REM @echo offREM setlocal disabledelayedexpansionecho "%~1" > temp.txtpausefor /f "delims=;" %%F in ('%~1') do (for /f "delims=;" %%F in ('%~1') do (echo %%F>>temp.txt)pausedel /q destination.txtren temp.txt destination.txtspan>ren temp.txt destination.txtspan>

标签: windows file sorting batch-file


【解决方案1】:
@echo off
setlocal enabledelayedexpansion
set "prev="
echo "%~1"
copy /y destination.txt+"%~1" temp.txt >nul

(    
for /f "delims=" %%F in ('sort temp.txt') do (
  if "!prev!" neq "%%F" echo(%%F
  set "prev=%%F"
)
)>destination.txt
del temp.txt

应该对你有用(我没试过)

无需使用for /f 处理新文件 - copy a+b c 将 a 和 b 连接到 c 中。如果目的地已经存在,/y 会强制覆盖目的地。

然后处理每一行,如果此行与前一行不匹配,则回显从sort 读取的行 - 但“将字符串括在引号中”,以便批处理知道如果字符串包含空格,则将其作为单个单元处理或其他分隔符。

(...echo ...)>file 格式(重新)使用 echoed 数据创建文件,而不是将数据发送到屏幕。

【讨论】:

  • 很遗憾,排序命令会导致批处理挂起。不知道为什么,它不像是对数十亿行进行排序。我的测试文件每个只有 3 行单个字母。感谢您的帮助。
【解决方案2】:

如果我理解正确,那么这就足够了:

@echo off
:loop
   type "%~1" >>"c:\destination.txt"
   shift 
   if not "%~1"=="" goto :loop
sort < "c:\destination.txt" > "%temp%\random file.txt"
move "%temp%\random file.txt" "c:\destination.txt"

【讨论】:

    【解决方案3】:

    另存为批处理文件。这是一个混合批处理/jscript 文件。文件处理/排序在批处理部分完成。然后,调用javascript部分来消除重复的行。

    已编辑 - 适应 cmets

    @if (@This==@IsBatch) @then
    @echo off
    rem **** batch zone *********************************************************
    
        setlocal enableextensions disabledelayedexpansion
    
    rem If there are no files, nothing to do
        if "%~1"=="" goto endProcess
    
    rem Configure the output final file 
        set "outputFile=destination.txt"
        if not exist "%outputFile%" >"%outputFile%" break
    
    rem Configure and initialize temporary file
        set "tempFile=%temp%\%~nx0.%random%%random%.tmp"
        find /v "" <"%outputFile%" >"%tempFile%"
    
    rem Iterate over the file list sending output to temporary file and deleting input file
        for %%a in (%*) do (
            find /v "" <"%%a" >>"%tempFile%"
            rem del /q "%%a" 2>nul 
        )
    
    rem Process temporary file into outpufile, sorting and eliminating duplicates    
        type "%tempFile%" | sort  | cscript //nologo //e:Javascript "%~f0" > "%outputFile%"
    
    rem Cleanup    
        del /q "%tempFile%" 2>nul
    
    :endProcess 
        endlocal
        exit /b
    
    @end
    // **** Javascript zone *****************************************************
        var stdin=WScript.StdIn, stdout=WScript.StdOut, previous=null, current;
        while (!stdin.AtEndOfStream){
            if (previous !== (current=stdin.ReadLine())) stdout.WriteLine(current);
            previous = current;
        };
    

    【讨论】:

    • 谢谢你,MC ND。我知道这在很大程度上是如何工作的。它似乎可以完美地处理两个文件,但是一次拖动两个以上的文件会导致它与某些行重叠。另外,如果我希望它在执行过程中删除源文件,我将如何完成此操作?
    • @RADRaze2KX,如果输入文件中的行不以 CRLF 结尾,则会发生行重叠。使用 find 过滤器更改了 type 命令以强制包含行终止符。在输入文件上添加了一个循环,以允许在处理它们时删除(但包括rem,如果它适合您,请将其删除)。
    • 这个似乎在我的桌面 (Windows Server 2012) 上完美运行,但在运行 Windows 8.1 的笔记本电脑上似乎无法运行。我还没有尝试过其他操作系统,但你知道为什么会这样吗?到目前为止,这是一个完美的程序,感谢您的努力。
    • 我删除了 REM 并没有删除文件。没关系,我想我现在更喜欢这样。 javascript完成操作后,有没有办法可以将完成的文件放在某个地方?我有一个将文件上传到我的网络服务器的代码,但不确定将其粘贴在哪里。我总是可以制作一个父批处理文件并运行它来运行这个批处理文件,然后是上传器。
    • @RADRaze2KX,请在清理之后和:endProcess 之前致电您的上传者。此时您已拥有该文件,并且可以调用该过程的其余部分。对于操作系统问题,这取决于您的配置。它应该从 XP 开始工作。什么在您的 8.1 中不起作用?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-23
    • 2014-01-06
    • 2019-11-19
    • 2020-08-04
    • 1970-01-01
    • 2018-11-20
    • 1970-01-01
    相关资源
    最近更新 更多