![批处理文件:将一个文件的内容复制到不同目录中的另一个文件](https://linux22.com/image/1629548/%E6%89%B9%E5%A4%84%E7%90%86%E6%96%87%E4%BB%B6%EF%BC%9A%E5%B0%86%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6%E7%9A%84%E5%86%85%E5%AE%B9%E5%A4%8D%E5%88%B6%E5%88%B0%E4%B8%8D%E5%90%8C%E7%9B%AE%E5%BD%95%E4%B8%AD%E7%9A%84%E5%8F%A6%E4%B8%80%E4%B8%AA%E6%96%87%E4%BB%B6.png)
我想创建一个批处理文件来合并两个文本文件的内容:
c:\folder1\1.txt
然后c:\folder2\2.text
将其附加到另一个文件c:\folder3\combine.txt
批处理文件(copy.bat)所在的位置。目录结构如下:
Folder PATH listing
Volume serial number is A0AD-DC56
C:.
+---Folder 1
| \---With
| \---Name
| \---Path
| \---Too
| \---Large
| 1.txt
|
+---Folder 2
| \---With
| \---Name
| \---Path
| \---Too
| \---Large
| 2.txt
|
\---Folder 3
\---With
\---Name
\---Path
\---Too
\---Large
Combine.txt
Copy.bat
我试过:
copy "c:\folder1\1.txt" + "c:\folder2\2.text" "c:folder3\combine.txt"
有没有其他方法可以使用命令cd
来更改目录并合并文件而不是提供文件的路径来更改目录?
答案1
电源外壳:
Set-Location 'c:\Folder3'
$FIle1 = 'c:\Folder1\1.txt'
$FIle2 = 'c:\Folder2\2.txt'
(Get-Content $File1 ) + (Get-Content $File2 ) | Set-Content 'Combine.txt'
将以上内容复制到文本编辑器中 $ 在 Folder3 中另存为MyCopy.ps1
。通过指定路径启动:c:\FOlder3\Mycopy.ps1
或.\MyCopy.ps1
答案2
Edit /*
观察:关于您的文件copy.bat
,尽量不要command
为批处理使用名称或在使用命令行时始终使用/执行其扩展名,但通过单击您不会遇到任何问题:> copy.bat
@echo off
set "_x="<nul && goto :_main
:_subst
for %%d in (Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E)do >nul 2>&1 (
%__APPDIR__%subst.exe %%~d: "%~1" && set "_rmv_drv_%~2=%%~d" && (
set "_dir_%~2=%~1" && exit /b ) )
:_main
setlocal enabledelayedexpansion
for %%i in (
"C:\Users\ecker\AppData\Local\Temp\Temporary ASP.NET Files"
"C:\Users\ecker\AppData\Local\Temp\NVIDIA Corporation"
"C:\Users\ecker\AppData\Local\Temp\Discord Crashes"
)do set /a "_x+=1+0" && call :_subst "%%~si" !_x!
copy /y /b "!_dir_1!\1.txt" + "!_dir_2!\2.txt" "!_dir_3!\Combine.txt.txt"
rem :: or..
copy /y /b "!_dir_1!\1.txt" + "!_dir_2!\2.txt" + "!_dir_3!\Combine.txt" "!_dir_3!\Combine.txt"
%__APPDIR__%subst.exe
rem :: do more task... after this, you can remove your tmp drivers ::
for /L %%L in (1 1 !_x!)do %__APPDIR__%subst.exe /D !_rmv_drv_%%L!: && (
echo\^| Removed ^| Drive: !_rmv_drv_%%L!:\: =^> !_dir_%%L! )
endlocal & goto :eof
1.要处理非常长的路径,您可以尝试使用:
subst avaliable-drive "c:\folder\far\far\away"
subst Z: "c:\folder\far\far\away"
2.当不再需要时,删除drive
与您的文件夹路径关联的内容:
subst avaliable-drive "c:\folder\far\far\away"
subst Z: "c:\folder\far\far\away"
subst /D Z:
- 观察:我觉得我迷失了步骤列表的顺序,请忽略这部分:)
3.使用前subst
,您可以缩短文件夹的路径,还可以组织创建方式,以便将来删除创建的驱动器,从而自动执行以下步骤:
3.1:for
根据我的示例文件夹,使用循环整齐地列出文件夹
for %%i in (
"C:\Users\ecker\AppData\Local\Temp\Temporary ASP.NET Files"
"C:\Users\ecker\AppData\Local\Temp\NVIDIA Corporation"
"C:\Users\ecker\AppData\Local\Temp\Discord Crashes"
)do ...
3.2:你用%%~si
在循环中扩展/更改变量中存在的路径%%i
,用于缩短为路径/字符串格式Short 8.3
,如果存在:
for %%i in (.)do set ... && ... "%%~si"...
- 观察:您可以检查此功能是否已启用,如果未启用,则需要管理员权限才能执行:
> %__APPDIR__%fsutil.exe 8dot3name query c:
The registry state is now: 0 (Enable 8dot3 name creation on all volumes).
> %__APPDIR__%fsutil.exe behavior set disable8dot3 0
The volume state is: 0 (8dot3 name creation is enabled).
The registry state is: 0 (Enable 8dot3 name creation on all volumes).
Based on the above settings, 8dot3 name creation is enabled on C:
3.3:使用计数器来方便按顺序使用文件夹,并使用它来定义变量并在不再需要时删除它们
for %%i in (.)do set /a "_x+=1+0"...
3.4:使用label
测试每个驱动器(按相反顺序)以找到一个可以使用的驱动器subst
,作为参数发送,文件夹的路径已经缩短(%%~si
),并保存计数器值(!_x!
)
call :_subst "%%~si" !_x!
观察:在调用标签/函数之前增加计数器
)do set /a "_x+=1+0" && call :_subst "%%~si" !_x!
3.5:在label/function
测试驱动程序的可用性,当找到时,它将通过&&
(return 0
) 运算符,则会发生后续执行(稍后解释)
:_subst
for %%d in (Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E
)do subst %%~d: "%~1" && execute ...
call :label <parameter 1> <parameter 2>
call :_subst "the sort path in loop" counter
call :_subst "%%~si" !_x!
3.6:在函数中,它将使用缩短的路径(%~1
),尝试逐个字母与路径(参数1)关联,当此执行returns 0
,那么它还将使用参数 2(%~2
== 序列号),保存相关驱动器的字母变形,以便在不再需要时删除,同时立即退出循环和函数:
:_subst
for %%d in (Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E)do >nul 2 >&1 (
%__APPDIR__%subst.exe %%~d: "%~1" && set "_rmv_drv_%~2=%%~d" && (
set "_dir_%~2=%~1" && exit /b ) )
3.7:从标签返回的操作基本上是按顺序定义的变量和值的组合,以及通过分配单元/驱动程序与文件夹的相应关联:
:_subst
%__APPDIR__%subst.exe Z: "C:\Users\ecker\...~1" && set "_rmv_drv_1=%%~d" && (
set "_dir_1="C:\Users\ecker\...~1" && exit /b ) )
rem :: some possible variable results for drives Z:, X: and Y:
Folder Variables:
!_dir_1! == "C:\Users\ecker\AppData\Local\Temp\DISCOR~1"
!_dir_2! == "C:\Users\ecker\AppData\Local\Temp\NVIDIA~1"
!_dir_3! == "C:\Users\ecker\AppData\Local\Temp\TEMPOR~1.NET"
Driver Save/Remove Variables:
!_rmv_drv_1! == Z:\
!_rmv_drv_2! == Y:\
!_rmv_drv_3! == X:\
3.8:现在您有了变量,就可以使用每个按顺序创建的变量,并根据相应的用途传递命令,完成任务后,您可以删除(应该!)相关的驱动器(接下来解释):
copy /y /b "!_dir_1!\1.txt" + "!_dir_2!\2.txt" "!_dir_3!\combine.txt"
3.8:现在是时候删除关联的单元了,并且知道它们是按数字顺序排列的,您可以使用循环For /L
,在定义的范围内,它将值增加到最大值(元素也是预先定义的,start, step, end
),并与变量连接,可以恢复值并传递删除命令:
for /L %%L in (1 1 !_x!)do %__APPDIR__%subst.exe /D !_rmv_drv_%%L!: && (
echo\^| Removed ^| Drive: !_rmv_drv_%%L!:\: =^> !_dir_%%L! )
Driver Save/Remove Variables:
!_rmv_drv_1! == Z:\ %%L == 1
!_rmv_drv_2! == Y:\ %%L == 2
!_rmv_drv_3! == X:\ %%L == 3
| Removed | Drive: Z:\: => C:\Users\ecker\AppData\Local\Temp\TEMPOR~1.NET
| Removed | Drive: Y:\: => C:\Users\ecker\AppData\Local\Temp\NVIDIA~1
| Removed | Drive: X:\: => C:\Users\ecker\AppData\Local\Temp\DISCOR~1
观察但是,如果你的路径比《怪物史莱克》中的“遥远的地方”要远得多,那么所有这些选项都可能致命失败,请参阅限制:
cmd中的路径长度:
- 如果环境变量包含的字符超过 8,191 个,CMD shell 将无法读取该环境变量 如果是这种情况,我建议将您的工作迁移到 PowerShell:
PowerShell 中的路径长度:
3.9因此,你可能需要检查一下在这里回答可以为您解决这个问题:
我经常遇到路径长度问题,大多数问题都是通过 cmd 解决的(当时我遇到的就是这个),但在那些时候,这里最有经验的用户可以更好地帮助您……您的问题很好,谢谢..
Edit */
你好像忘记了\
并在目标文件中使用完整路径:
copy "c:\folder1\1.txt" + "c:\folder2\2.text" "c:\folder3\combine.txt"
观察:1当你从任何文件夹或驱动器调用你的 bat 时,命令行解释器(cmd.exe)必须定义一个工作目录,但是你的命令不提供任何驱动器或文件夹,只有一个独立的文件名。
copy /b "c:folder1\1.txt" + "c:folder2\2.text" combine.txt
观察:2要定义文件复制的工作目录destination
以及您的 bat 的其他可能操作,folder3
请使用“添加相应的驱动器/文件夹cd /d "drive\folder"
或者,如果相同“drive/folder
作为你的球棒,你可以使用cd /d "%~dp0"
或者pushd "%~dp0"
- 添加
CD
或者Pushd
定义你的工作目录以及哪个文件夹与你的 bat 将启动和运行的文件夹是同一个文件夹:
@echo off
cd /d "%~dp0"
rem :: or...
pushd "%~dp0"
rem :: or...
cd /d "folder3"
copy "c:\folder1\1.txt" + "c:\folder2\2.text" "combine.txt"
rem :: more commands here
popd
- 无需添加
CD
或者Pushd
,你可以将其set
用于你的文件夹:
@echo off
set "_var_1=c:\folder1"
set "_var_2=c:\folder2"
set "_var_3=c:\folder3"
copy "%_var_1%\1.txt" + "%_var_2%\2.txt" "%_var_3%\Combine.txt"
进一步阅读: