Board logo

标题: [文本处理] 求助批处理随机抽取文件夹中的txt文件并合并 [打印本页]

作者: xudewu    时间: 2020-9-15 17:20     标题: 求助批处理随机抽取文件夹中的txt文件并合并

比如说目录下有文件夹1,文件夹a,文件夹A,
文件夹1下面有1.txt,2.txt,3.txt
文件夹a下面有a.txt,b.txt,c.txt
文件夹A下面有A.txt,B.txt,C.txt

我想在每个文件夹下面随机抽取1个文件,运行一次合并成新的1个txt文件,文件夹和里面的内容顺序不变,原文件保留。
比如运行一次随机生成一个2cA的内容或者1bB的内容。
不知道如何实现,恳请大佬帮忙。
作者: Batcher    时间: 2020-9-15 17:27

回复 1# xudewu


    Windows不允许在同一个目录下创建文件夹a,文件夹A,系统会认为它们是重名的。
作者: xudewu    时间: 2020-9-15 17:44

回复 2# Batcher
学到了,这个也只是举个例子,为了说明文件夹名称的区别以及排序,实际应用时不是这个名称的。
把文件夹名称改改成文件夹1,文件夹2,文件夹3呢?不知以上如何实现。
作者: qixiaobin0715    时间: 2020-9-16 16:50

回复 3# xudewu
说一说思路:
1.用for循环取得文件名并进行编号;
2.循环体外用%random%取得随机编号,在三个文件夹中按随机编号分别抽取其中一个文件;
3.合并抽取文件。
作者: Batcher    时间: 2020-9-16 22:39

回复 1# xudewu


请参考Q-04和Q-05把bat文件和txt文件都保存为ANSI编码:
https://mp.weixin.qq.com/s/6lbb97qUOs1sTyKJfN0ZEQ
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "MergeFile=All.txt"
  4. >"%MergeFile%" type nul
  5. for %%a in ("a" "b" "c") do (
  6.     pushd %%a
  7.     for /f "delims=" %%i in ('dir /b /a-d') do (
  8.         set "_%%~nxa_!random!=%%~nxa\%%i"
  9.     )
  10.     for /f "tokens=2 delims==" %%i in ('set _%%~nxa') do (
  11.         set "RandFile=%%i"
  12.     )
  13.     popd
  14.     >>"%MergeFile%" type "!RandFile!"
  15.     >>"%MergeFile%" echo,
  16. )
复制代码
扩展阅读:批处理生成随机数字和随机字符串
https://mp.weixin.qq.com/s/D6AfUmKYm4DoD_KeazGHdA
作者: Batcher    时间: 2020-9-16 22:49

回复 1# xudewu


第二种思路
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. set "MergeFile=All.txt"
  4. >"%MergeFile%" type nul
  5. for %%a in ("a" "b" "c") do (
  6.     pushd %%a
  7.     set n=0
  8.     for /f "delims=" %%i in ('dir /b /a-d') do (
  9.         set /a n+=1
  10.         set "_!n!=%%~nxa\%%i"
  11.     )
  12.     set /a RandNum=!random!%%^(3-1+1^)+1
  13.     call set "RandFile=%%_!RandNum!%%"
  14.     popd
  15.     >>"%MergeFile%" type "!RandFile!"
  16.     >>"%MergeFile%" echo,
  17. )
复制代码

作者: qixiaobin0715    时间: 2020-9-17 16:45

回复 1# xudewu

如果要从当前目录下所有一级文件夹中分别随机抽取一个文件(txt),进行合并,而不是指定的三个文件夹的话,可以这样:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. for /d %%i in (*) do (
  4.   set /a n=0
  5.   for %%a in ("%%i\*.txt") do (set /a n+=1 & set r!n!=%%~fa)
  6.   set /a s=!random!%%!n!+1
  7.   call set "Stochastic=%%r!s!%%"
  8.   type "!stochastic!">>all.txt
  9. )
  10. pause
复制代码

作者: xudewu    时间: 2020-9-18 10:33

回复 6# Batcher


    非常完美,感谢感谢
作者: xudewu    时间: 2020-9-18 10:44

回复  xudewu

如果要从当前目录下所有一级文件夹中分别随机抽取一个文件(txt),进行合并,而不是指定 ...
qixiaobin0715 发表于 2020-9-17 16:45



    也很实用,所有文件夹提取本来担心组合好的文档排序问题,测试了一下用字母把文件夹排好序效果也不错。
作者: Batcher    时间: 2020-9-18 11:04

20200812
20200812data.txt
20200812lisidata.txt
20200812wangwudata.txt
20200812dongyitable.txt
20200812lintable.txt
、、、、
、、、
20200915
20200915liwutable.txt
20200915chendata.txt
20200915lintttable.txt

20200812为文件夹 *.txt的为文件。需要把从20200812文件夹名称开始到20200915结束文件夹下所有的table.txt结尾的文件 输出到onlinetale.txt文件中,data.txt结尾的文件输出到onlinedata.txt


test1.bat
  1. @echo off
  2. type nul >"onlinetale.txt"
  3. type nul >"onlinedata.txt"
  4. for /f "delims=" %%i in ('dir /b /ad') do (
  5.     dir /b /a-d "%%i\*table.txt" >>"onlinetale.txt"
  6.     dir /b /a-d "%%i\*data.txt" >>"onlinedata.txt"
  7. )
复制代码
test2.bat
  1. @echo off
  2. type nul >"onlinetale.txt"
  3. type nul >"onlinedata.txt"
  4. for /f "delims=" %%i in ('dir /b /ad') do (
  5.     (for /f "delims=" %%j in ('dir /b /a-d "%%i\*table.txt"') do (
  6.         type "%%j"
  7.     ))>>"onlinetale.txt"
  8.     (for /f "delims=" %%j in ('dir /b /a-d "%%i\*data.txt"') do (
  9.         type "%%j"
  10.     ))>>"onlinedata.txt"
  11. )
复制代码

作者: qixiaobin0715    时间: 2020-9-18 16:09

回复 6# Batcher

对于pushd,popd命令一直很迷茫。就知道用pushd标记路径,然后popd恢复路径。
就这里来说吧
1.“pushd %%a”标记的是当前目录的路径还是当前目录下的一级目录的路径?
2.popd前面的位置路径发生了什么变化?为什么要恢复路径?
作者: Batcher    时间: 2020-9-18 16:42

回复 11# qixiaobin0715


看下这个教程是否可以理解
http://bbs.bathome.net/thread-13988-1-1.html
作者: qixiaobin0715    时间: 2020-9-18 17:59

本帖最后由 qixiaobin0715 于 2020-9-18 18:00 编辑

回复 12# Batcher

仔细进行学习,好像明白了一些。
1.“pushd %%a”标记了当前目录的下一级目录的路径(也即是内部循环体的路径)?
2.里面的for循环得到的"_!n!=%%~nxa\%%i"只是文件名及扩展名。跳出循环后,"%%_!RandNum!%%"要想和"_!n!=%%~nxa\%%i"关联,就需要回到上面标记的路径。
不知这样理解的是否正确?
作者: Batcher    时间: 2020-9-18 22:16

回复 13# qixiaobin0715


    有一小部分不太准确,"_!n!=%%~nxa\%%i"蓝色是文件名及扩展名,红色是文件夹名
作者: qixiaobin0715    时间: 2020-9-19 11:19

回复 14# Batcher

确实理解还是有偏差,多亏提醒:
1.外部for循环第一次标记" pushd %%a" 的路径是 "当前目录\a\" ,内部的 "for /f" 循环默认在 "当前目录\a\" 运行,就不再需要指定路径。
2.下面popd恢复路径后,回到了 "当前目录\" ,又要与子文件夹"a\"下的文件关联,所以内部循环赋值时要在文件名前面加上子文件夹名,即"%%~nxa\%%i"。
作者: qixiaobin0715    时间: 2020-9-21 14:09

本帖最后由 qixiaobin0715 于 2020-9-21 14:37 编辑

好像这里用 "cd" 指定路径也可以:
用"cd %%a" 替代 "pushd %%a"
用 "cd %~dp0" 或 "cd.." 替代 "popd"




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2