Board logo

标题: [已结]如何根据文 本 文 件的内容拷贝数据 [打印本页]

作者: lsjiang     时间: 2008-11-7 23:54    标题: [已结]如何根据文 本 文 件的内容拷贝数据

详细内容: 根据文本文件的路径及文件名拷贝文件到指定路径下,并在该路径下建立相同的路径.例如:文本文件 a.txt 内容如下: e:\book\abc\sample1.pdf e:\book\abc\sample2.pdf e:\book\abc\sample3.pdf 想拷贝sample1.pdf、sample2.pdf、sample3.pdf 到 f盘 ,并在f盘得到与e盘相同的目录结构:首先判断f盘中有没有book文件夹,如果没有则建一个book文件夹,然后再判断book有没有abc文件夹,如果没有则建一个abc文件夹,最后把三个文件拷贝到该文件夹中。 请教各位大侠,用批处理的方式能不能实现,多谢! [ Last edited by lsjiang on 2008-11-13 at 17:14 ]

作者: lsjiang     时间: 2008-11-8 00:54
请大侠们费费心,多谢了!

作者: tireless     时间: 2008-11-8 01:02
@echo off
for /f "delims=" %%a in (a.txt) do (
  if not exist "F:%%~pa" md "F:%%~pa"
  copy /y "%%a" "F:%%~pa"
)

作者: lsjiang     时间: 2008-11-8 07:26
测试通过,完全实现所需功能! 非常感谢tireless!

作者: lsjiang     时间: 2008-11-8 08:53
补充求助: 能不能在批处理中同时实现把文本文件a.txt中已拷贝的文件行删除?

作者: tireless     时间: 2008-11-8 09:58
Originally posted by lsjiang at 2008-11-8 08:53 AM: 补充求助: 能不能在批处理中同时实现把文本文件a.txt中已拷贝的文件行删除?
也就是说 a.txt 列表中的有些文件是不存在的是吗?将不存在的路径保存到 b.txt:
@echo off
for /f "delims=" %%a in (a.txt) do (
  if not exist "F:%%~pa" md "F:%%~pa"
  copy /y "%%a" "F:%%~pa" >nul || >>b.txt echo %%a
)

作者: lsjiang     时间: 2008-11-8 10:44
首先感谢tireless的不吝赐教! 补充中的意思也可以这样理解:把a.txt中已经拷贝完成的行删除! 是不是可以这样处理:把已经拷贝完成的文件夹及文件列出一个完整目录到另外一个文件文件b.txt中,然后比较a.txt和b.txt,从a.txt删除b.txt中有的行?(假设同一行中后面15个字符相同就视为此行相同) 我是新手,不知道用批处理能不能实现这样的功能? [ Last edited by lsjiang on 2008-11-8 at 10:55 ]

作者: tireless     时间: 2008-11-8 11:02    标题: Re 7 楼

6 楼的代码不行么?

作者: lsjiang     时间: 2008-11-8 11:25
6楼的代码基本能实现所需目标,再请教一个问题:如果目标盘F盘空间不足的话,6楼的代码能正常执行吗?

作者: tireless     时间: 2008-11-8 11:27    标题: Re 9 楼

不行的吧

作者: lsjiang     时间: 2008-11-8 11:57
空间不足,拷贝不成功,会报错退出呢,还是能够继续执行“|| >>b.txt echo %%a”,把没有执行成功的部分输出到b.txt中呢?

作者: tireless     时间: 2008-11-8 13:32
Originally posted by lsjiang at 2008-11-8 11:57 AM: 空间不足,拷贝不成功,会报错退出呢,还是能够继续执行“|| >>b.txt echo %%a”,把没有执行成功的部分输出到b.txt中呢?
应该是会把没有执行成功的部分输出到b.txt中。你自己测试吧,把一个盘的空间填满,然后... ...我的256MB内存的机器就不做测试了。 [ Last edited by tireless on 2008-11-8 at 13:34 ]

作者: lsjiang     时间: 2008-11-8 14:59
已经过测试:会把没有执行成功的部分输出到b.txt中,只是会显示很多“磁盘空间不足”的提示,直到把所有没拷贝成功的行都显示一遍才会执行后面的命令。 请问:如果a.txt文件中行数很多的话,显示时间会较长,如何在第一个“磁盘空间不足”的提示后即停止拷贝,执行后面的输出命令? 麻烦了,再次表示感谢!

作者: tireless     时间: 2008-11-8 15:45    标题: Re 13 楼

@echo off
for /f "delims=" %%a in (a.txt) do (
  if not exist "F:%%~pa" md "F:%%~pa"
  if not exist "%%a" (>>b.txt echo %%a) else copy /y "%%a" "F:%%~pa" >nul || pause & exit /b
)

作者: lsjiang     时间: 2008-11-8 16:20
14楼的代码运行不成功,没有创建b.txt。可能是我没表达清楚。 6楼的代码已经基本能够达到目标,有个问题是在磁盘空间不足的情况下,一定要等到a.txt中所有行都执行完后才能进行输出动作,如果手动结束的话,后面的命令不执行就得不到b.txt。 我的意思是在在磁盘空间不足的情况下直接结束拷贝动作,并将没有成功拷贝的行输出到b.txt。 另外:if not exist "%%a" (>>b.txt echo %%a) 这句的意思没看明白,麻烦帮解释一下。谢谢 [ Last edited by lsjiang on 2008-11-8 at 16:29 ]

作者: tireless     时间: 2008-11-8 16:47
if not exist "%%a" (>>b.txt echo %%a) else copy /y "%%a" "F:%%~pa" >nul || pause & exit /b 这句的意思是: 如果文件不存在,则把文件路径输出到 b.txt。如果文件存在就执行 else 后面的语句了 —— 复制文件,而如果不成功的话就暂停接着退出。 14 楼的代码确实不会将“磁盘空间不足”时没有被复制的文件路径输出到 b.txt,只将不存在的文件路径输出到 b.txt。再试试以下代码:
@echo off
for /f "delims=" %%a in (a.txt) do (
  if not exist "F:%%~pa" md "F:%%~pa"
  if not exist "%%a" (>>b.txt echo %%a) else copy /y "%%a" "F:%%~pa" >nul || (
    >>b.txt echo %%a
    pause & exit /b
  )
)
[ Last edited by tireless on 2008-11-8 at 16:49 ]

作者: lsjiang     时间: 2008-11-8 16:59
16楼的代码只将最后一行没有拷贝成功的内容输出到了b.txt,a.txt后面的部分没有输出到b.txt中,批处理就退出了。仍然有缺憾。 请再次赐教!

作者: tireless     时间: 2008-11-8 18:09
@echo off
for /f "delims=" %%a in (a.txt) do (
  if not exist "F:%%~pa" md "F:%%~pa"
  if not exist "%%a" (>>b.txt echo %%a) else copy /y "%%a" "F:%%~pa" >nul || (
    >>b.txt echo %%a
    for /f "delims=:" %%? in ('findstr /n "%%a" a.txt') do more +%%? a.txt >> b.txt
    pause & exit /b
  )
)

作者: lsjiang     时间: 2008-11-9 00:27
tireless:老麻烦你实在不好意思。 18楼的代码测试与16楼的结果是一样的。也是只把最后一行没有拷贝成功的内容输出到了b.txt,显示了一行磁盘空间不足后,任意键就退出了。 麻烦再想想还没有有更好的方案?

作者: tireless     时间: 2008-11-9 00:52
是我不好意思...功力不够却老爱去回答别人的问题,总是会出现错误,很抱歉。先去 sleep 了,明天再想想...

作者: lsjiang     时间: 2008-11-9 01:09
共同探讨共同进步,我从你的回答里也学到了不少东西,给我很多启发,总之多谢你的热心相助!祝你晚安。

作者: HAT     时间: 2008-11-9 01:45    标题: Re 20楼

任何人都是从不会到会走过来的,古人教育我们:闻道有先后,术业有专攻,如是而已。 tireless 兄不必过谦,你乐于助人的精神值得所有人学习。

作者: tireless     时间: 2008-11-9 11:19
Originally posted by lsjiang at 2008-11-9 12:27 AM: 18楼的代码测试与16楼的结果是一样的。也是只把最后一行没有拷贝成功的内容输出到了b.txt,显示了一行磁盘空间不足后,任意键就退出了。 麻烦再想想还没有有更好的方案?
那就奇怪了...
copy /y "%%a" "F:%%~pa" >nul || ( >>b.txt echo %%a for /f "delims=:" %%? in ('findstr /n "%%a" a.txt') do more +%%? a.txt >> b.txt pause & exit /b )
括号里的第一行和第三行都执行成功,怎么第二行就没执行成功呢?

作者: lsjiang     时间: 2008-11-9 19:44
我又来了,呵呵! 这样做是不是容易些。直接把拷贝完成的行从a.txt中删掉,不用把没拷贝的行输出到b.txt了,剩下的就是没有拷贝完成的。容易实现否?

作者: tireless     时间: 2008-11-9 21:17
找到原因了,因为: findstr /n "e:\book\abc\sample1.pdf" a.txt 文件名与扩展名中间的点在 findstr 中有特殊意义。而换成使用 /c: 碰到中文也会有问题: 找得到: findstr /n /c:"e:\book\abc\i'm here.pdf" a.txt 找不到: findstr /n /c:"e:\book\abc\找不到 我.pdf" a.txt —————————————————————————————————————————————————— 使用 find.exe 来找就没问题了。代码:
@echo off
for /f "delims=" %%a in (a.txt) do (
  if not exist "F:%%~pa" md "F:%%~pa"
  if not exist "%%a" (>>b.txt echo %%a) else copy /y "%%a" "F:%%~pa" >nul || (
    >>b.txt echo %%a
    for /f "skip=2 delims=[]" %%i in ('find /n "%%a" a.txt') do more +%%i a.txt >> b.txt
    pause & exit /b
  )
)
[ Last edited by tireless on 2008-11-9 at 22:52 ]

作者: lsjiang     时间: 2008-11-9 22:46
OK,测试通过,完全达到要求。 对tireless的热心相助表示万分感谢!

作者: lsjiang     时间: 2008-11-10 10:48
再请教一下:我用tireless的方法成功实现了所需功能,有个小问题,如果a.txt 中没有拷贝成功的行超过65535的话,用more输出就有问题了,如何突破呢? 如果用把拷贝成功的行删除话如何实现呢? 用下面的代码会把源文件中的文件删除了,如何只删除a.txt中已拷贝的行呢? @echo off for /f "delims=" %%a in (a.txt) do ( if not exist "F:%%~pa" md "F:%%~pa" if not exist "%%a" (>>b.txt echo %%a) else copy /y "%%a" "F:%%~pa" >nul && del %%a [ Last edited by lsjiang on 2008-11-10 at 17:47 ]

作者: tireless     时间: 2008-11-11 01:22    标题: 那不用 more,用 for 好了。

@echo off
for /f "delims=" %%a in (a.txt) do (
  if not exist "%%a" (>>b.txt echo %%a) else (
    if not exist "F:%%~pa" md "F:%%~pa"
      copy /y "%%a" "F:%%~pa" >nul || (
        echo 正在输出未被复制的文件路径至 b.txt...
        >>b.txt echo %%a
        for /f "skip=2 delims=[]" %%i in ('find /n "%%a" a.txt') do (
          set n=%%i
          goto end
        )
      )
  )
)

:end
for /f "skip=%n% delims=" %%o in (a.txt) do echo %%o>>b.txt
echo   输出完毕。请按任意键退出...
pause>nul & exit /b
[ Last edited by tireless on 2008-11-12 at 15:25 ]

作者: lsjiang     时间: 2008-11-11 11:33
这样就没有什么问题了。非常感谢!