2017-05-26 33 views
0

我有6个文本文件。每个播放列表都是一个播放列表,具体来说,每个播放列表在每行上都包含完全限定的文件名,它们都位于同一个目录中。但是6个播放列表中的每一个都包含来自不同文件夹的文件。另外,每个播放列表都按字母顺序排序。如何将多个文本文件合并为一个文件,保持每个文件的排序,但合并排序所有

我想将它们全部合并到一个文本文件中,其中包含所有单个文本文件中的所有行。

我想订单是随机的。但是,我希望6个文本文件中的每一个文件的排序顺序都得到遵守。

所以结果可能这样开始:

C:\DirectoryE\fsdkfhj.avi 
C:\DirectoryA\jsazlkfjh.mp4 
C:\DirectoryC\aldfkgdl.avi 
C:\DirectoryD\basfjkdfhdksdkj.avi 
C:\DirectoryE\gsdfsad.mp4 
C:\DirectoryD\mfsdhsfjs.avi 
C:\DirectoryA\nsdfkghkjhdf.mpg 
C:\DirectoryE\hfdsskdfkemn.mp4 
C:\DirectoryB\afdskfdfk.mpg 

(忽略的文件扩展名 - 他们只是一个例子,这显然不影响按字母顺序排列的文件名排序。)

但是请注意目录做不需要按顺序(应该是随机的)。但是任何给定目录中的文件名都应该按字母顺序排列。

DOS批处理文件中的解决方案将是首选,在Java解决方案也是可以接受的。谢谢!

编辑:我会在28小时内提供对这些解决方案的回应。我可以这么说,没有测试他们都看起来可行。我被这些解决方案中展现的创造力所吸引,并且他们提供的速度如此之快。我不知道这是stackexchange如何工作。有一天我会回报这种慷慨。

+1

哪一部分导致您的困难? –

+1

和你有什么尝试,直到现在呢? –

+1

请不要将StackOverflow与免费的代码/脚本编写服务混淆!你需要分享你的努力,并准确地描述你卡住的地方!请学习[问]! – aschipfl

回答

1
@ECHO Off 
SETLOCAL 
SET "sourcedir=U:\sourcedir" 
SET "destdir=U:\destdir" 
SET "filenames=file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt" 
SET "outfile=%destdir%\outfile.txt" 
:: remove variables starting $ 
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a=" 
SET /a filecount=0 
SET /a itemcount=0 
SET /a maxtracks=0 
FOR %%a IN (%filenames%) DO CALL :getname "%sourcedir%\%%~a" 
) 


:: Now DO the selection 
:select 
SET /a selection=(%RANDOM% %% filecount) + 101 
FOR /L %%t IN (1,1,%maxtracks%) DO IF DEFINED $%selection%%%t (
CALL >>"%outfile%" ECHO %%$%selection%%%t%% 
set "$%selection%%%t=" 
SET /a itemcount-=1 
GOTO done 
) 
:done 
IF %itemcount% gtr 0 GOTO select 


GOTO :EOF 
:: get tracknames and store to $1??? 
:getname 
SET /a filecount+=1 
SET /a dollar=filecount+100 
SET /a tracks=0 
FOR /f "tokens=1*delims=[]" %%p IN (
'find /n /v "" ^<"%~1"' 
) DO SET "$%dollar%%%p=%%q"&SET /a itemcount+=1&SET /a tracks+=1 
IF %tracks% gtr %maxtracks% SET /a maxtracks=tracks 
GOTO :eof 

你需要改变的sourcedirdestdir设置以适合你的情况。

主要生产定义为%OUTFILE%

有趣的练习文件 - 即使是严格写入一个规范的请求。因为你没有向我们显示任何代码。

对于每个文件,读取每行并将其记录在变量$filenumber + 100linenumber。还要统计每个单独播放列表中的曲目数量,并计算任何单个播放列表中的曲目最大数量。

原因filenumber+100是,在扩展到最多99个文件时,文件1和文件10(或11)没有编号系统重叠。

具有记录每一个名字,先选择一个随机的播放列表(现在编号为101),并检测可变$playlisttracknumber是否存在,计数轨段编号从1到maxtracks。当检测到第一个时,输出其值并将其值设为,递减剩余的总项目并转到done,以便仅选择一个项目。

done我们选择了一个曲目或没有选择曲目,所以我们检查剩余的filecount。如果大于0,则重复选择过程,最终选择所有可用轨道,并且itemcount将终止于0。


@ECHO Off 
SETLOCAL 
SET "sourcedir=U:\sourcedir" 
SET "destdir=U:\destdir" 
SET "filenames=file1.txt file2.txt file3.txt file4.txt file5.txt file6.txt" 
SET "outfile=%destdir%\outfile.txt" 
:: remove variables starting $ 
FOR /F "delims==" %%a In ('set $ 2^>Nul') DO SET "%%a=" 
SET /a filecount=0 
SET /a itemcount=0 
SET /a maxtracks=0 
SET /a limits=0 
FOR %%a IN (%filenames%) DO CALL :getname "%sourcedir%\%%~a" 
) 
SET /a filecount=itemcount 
:: Now DO the selection 
:select 
SET /a nbr=(%RANDOM% %% filecount)+1 
SET /a selection=100 
FOR %%t IN (%limits%) DO IF %%t leq %nbr% SET /a selection+=1 
FOR /L %%t IN (1,1,%maxtracks%) DO IF DEFINED $%selection%%%t (
CALL >>"%outfile%" ECHO %%$%selection%%%t%% 
set "$%selection%%%t=" 
SET /a itemcount-=1 
GOTO done 
) 
:done 
IF %itemcount% gtr 0 GOTO select 


GOTO :EOF 
:: get tracknames and store to $1??? 
:getname 
SET /a filecount+=1 
SET /a dollar=filecount+100 
SET /a tracks=0 
FOR /f "tokens=1*delims=[]" %%p IN (
'find /n /v "" ^<"%~1"' 
) DO SET "$%dollar%%%p=%%q"&SET /a itemcount+=1&SET /a tracks+=1 
IF %tracks% gtr %maxtracks% SET /a maxtracks=tracks 
SET "limits=%limits% %itemcount%" 
GOTO :eof 

这里有一个稍微修订版本,补偿不同的轨道计数。

它构建了limits这是在读取每个文件后遇到的曲目总数的列表,因此如果有7,6和9个曲目,它可能被分配0 7 13 22。然后将filecount分配为与itemcount相同的值。

在这样做的选择,nbr设为1..totaltracks和selection然后被设定为100 + limits项,其是小于或等于nbr的数目。因此,对于nbr = 1..7,102,8.33和103对于14..22,selection设置为101。结果是选择的文件/专辑号码与专辑在曲目中的长度成比例地选择。

+0

谢谢!这在很大程度上起作用。但是,正如你所看到的,它最后以很多相同的目录结束。我怀疑那是因为那个目录有这么多的文件。但那是有效的!我可以按照这个顺序观看这些文件。非常感谢你的帮助,我只希望有一天我能帮你回报! – spacefaced

1
@echo off 
    setlocal enableextensions disabledelayedexpansion 

    set "counter=0" 
    for %%f in (*.txt) do (
     set "base=100000000" 
     set /a "counter+=1" 
     for /f "usebackq delims=" %%a in ("%%~ff") do (
      setlocal enabledelayedexpansion 
      set /a "base+=(!random!%%1000)*100+counter" 
      for %%b in (!base!) do (
       endlocal 
       set "_l.%%b=%%a" 
       set "base=%%b" 
      ) 
     ) 
    ) 
    for /f "tokens=1,* delims==" %%a in ('set _l.') do echo(%%b 

基本思想是在输入文件中的每一行前加上一个随机数,然后对这个数字进行排序。

  • 使用for命令迭代文件。它被写入处理该文件夹中的所有.txt文件。如果你更喜欢处理封闭列表,每个文件都使用for /f命令来读取该行更改为类似
 
    for %%f in (file1.txt file2.txt file3.txt x:\somewhere\otherfile.txt) do 
  • 对于每个文件,随机序列从100000000(填充)开始,并为每行添加随机数,为每个文件生成一个递增的数字序列并保持排序顺序。为避免为多个文件生成相同的随机值(文件中的一行可能会覆盖另一行中的行),将为每行生成的随机值乘以100,并添加一个计数器(每个文件增加一个)。

  • 读取的数据存储在使用生成的随机数命名的环境变量中。这样我们可以稍后检索数字排序的变量列表。

  • 一旦读取完所有数据,for /f命令将检索已定义变量的列表(已检索列表已排序)并输出其值。

+0

谢谢,MC ND!您的解决方案与Magoo的解决方案几乎完全相同。唯一的区别是,虽然他的结果的最后24行恰好是最长输入文件(“s1.txt”)的最后24行,但结果的最后30行恰好是“s1的最后30行”。文本”。然而,再一次,这可能是可以预料的,因为我从来没有说过“s1.txt”比其他输入文件长得多。我非常感谢你们在这个问题上花费你的时间,并帮助我找到解决方案。你们都是非常有才华和慷慨的灵魂。 – spacefaced

相关问题