我认为您遇到了 “Windows World” 和“Unix World”的冲突。
你正在尝试使用rsync,这是一个自然的 Unix 工具,是使用批处理文件路径复制并将其放入 rsync 路径。这行不通。
我会剖析你的代码:
在这一部分中,您仍处于“Windows 世界”中,您正在使用 FOR 以 Windows 方式 FOR /d %%A IN (U:\0012\*) DO 循环通过 U:\0012\* 路径。
您尝试使用 unix 样式路径 /cygdrive/U/0012/ 来“帮助”rsync,但变量 %%A 包含 windows 样式路径!
C:\cygwin\bin\rsync.exe -av -h --progress --checksum "/cygdrive/U/0012/%%A/*.*/" "/cygdrive/U/0012/%%A/EXAMPLE/"
你得到的错误可能是这样的:
源和目标不能都是远程的。 rsync 错误:语法
或 main.c(1292) [Receiver=3.1.2] 处的使用错误(代码 1)
如何解决这样的错误?
首先是说我正在使用MSYS linux 工具环境。我已经在我的本地文件上对其进行了测试。
在批处理文件中你可以这样做:
@echo off
FOR /d %%A IN (U:\0012\*) DO (
SET "copy_path=%%A"
C:\msys64\usr\bin\cygpath.exe -u %copy_path% > tmp_file.tmp
SET /P unix_path=<tmp_file.tmp
DEL tmp_file.tmp
ECHO "%unix_path%"
C:\msys64\usr\bin\rsync.exe -av -h --progress --checksum --remove-source-files "%unix_path%" "%unix_path%/EXAMPLE/"
)
)
脚本采用窗口路径C:\prg\PowerShell\test\SO\test1\*,然后使用cygpath.exe 将路径转换为unix 样式路径并将其保存到临时文件(tmp_file.tmp)。然后它从临时文件中读取到 unix 变量%unix_path% 的路径,然后在rsync.exe 中使用该变量。
注意:因为有人已经链接了如何使用 rsync 移动文件。我只会说明选项。你必须添加--remove-source-files,它会在传输后删除文件。
** 编辑 **
- 我想我现在明白你的意思了。现在
rsync 应该真的像移动一样。唯一的区别是如果目录example 存在,它会与文件一起复制。 (如果没有创建它并将文件移到那里)-我认为这是查看mkdir && move时的初衷。
我做了什么?
ENABLEDELAYEDEXPANSION 正确读取文件中的变量(在它只是最后一次读取之前)
"!unix_path!/" 最后一个反斜杠对于 rsync 正常运行非常重要。
我已经在我的电脑上测试了脚本,对我来说它可以正常工作。
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /D %%A IN (C:\prg\t\*) DO (
ECHO %%A
SET "copy_path=%%A"
C:\msys64\usr\bin\cygpath.exe -u !copy_path! > tmp_file.tmp
SET /P unix_path=<tmp_file.tmp
DEL tmp_file.tmp
ECHO "!unix_path!"
ECHO C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
)
** 第二次编辑 ** rsync 不会删除空目录
我不建议在一次操作中使用--remove-files && --delete 选项,因为 rsync 可能会失败。你可以在这里阅读更多内容superuser.com或unix stack exchange甚至server fault。
我会简单地使用已经写好的解决方案:How to delete empty folders using windows command prompt?(我说的是解决方案(所有作者的功劳),它也包含带空格的目录):
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
最终的脚本将如下所示:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /D %%A IN (C:\prg\t\*) DO (
ECHO %%A
SET "copy_path=%%A"
C:\msys64\usr\bin\cygpath.exe -u !copy_path! > tmp_file.tmp
SET /P unix_path=<tmp_file.tmp
DEL tmp_file.tmp
ECHO "!unix_path!"
ECHO C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
C:\msys64\usr\bin\rsync.exe -av --progress --checksum --remove-source-files "!unix_path!/" "!unix_path!/example/"
)
REM To delete empty directories - the windows way
REM save current directory to stack
pushd
cd C:\prg\t
REM Will delete all empty directories (subdirectories) at current path
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
REM return to saved directory
popd