如何使用rsync而不是批量移入for循环

Ole*_*_08 7 rsync for-loop batch-file

在路径U:\ 0012*中的每个子文件夹中,我创建一个示例文件夹,并将文件从适当的子文件夹移动到示例文件夹.

FOR /d %%A IN (U:\0012\*) DO mkdir %%~A\example & move %%~A\*.* %%~A\example\ 
Run Code Online (Sandbox Code Playgroud)

我想尝试的是使用rsync命令而不是移动

 FOR /d %%A IN (U:\0012\*) DO 
C:\cygwin\bin\rsync.exe -av -h --progress --checksum "/cygdrive/U/0012/%%A/*.*/" "/cygdrive/U/0012/%%A/EXAMPLE/" 
Run Code Online (Sandbox Code Playgroud)

该脚本因语法错误而自行关闭.是否可以在for循环中使用rsync?

tuk*_*kan 1

我认为你正在发生“Windows World”和“ Unix World ”的冲突。

您正在尝试使用的rsync是自然的 Unix 工具,即使用批处理文件路径进行复制并将其放入 rsync 路径中。这是行不通的。

我将剖析你的代码:

在这一部分中,您仍然处于“Windows 世界”中,您正在使用它以 Windows 方式FOR循环路径。U:\0012\*FOR /d %%A IN (U:\0012\*) DO

您尝试rsync使用 unix 样式路径“帮助” /cygdrive/U/0012/,但该变量%%A包含 windows 样式路径!

C:\cygwin\bin\rsync.exe -av -h --progress --checksum "/cygdrive/U/0012/%%A/*.*/" "/cygdrive/U/0012/%%A/EXAMPLE/"
Run Code Online (Sandbox Code Playgroud)

您收到的错误可能类似于:

源和目标不能同时位于远程。rsync 错误:main.c(1292) 处的语法或使用错误(代码 1)[Receiver=3.1.2]

出现这样的错误如何解决?

首先要说的是我正在使用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/"
    )
)
Run Code Online (Sandbox Code Playgroud)

该脚本采用 Window 路径C:\prg\PowerShell\test\SO\test1\*,然后使用 acygpath.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/"
)
Run Code Online (Sandbox Code Playgroud)

** 第二次编辑 ** rsync 不会删除空目录

我不建议在一项操作中使用--remove-files&&--delete选项,因为 rsync 可能会失败。您可以在这里阅读更多内容superuser.comUnix 堆栈交换甚至服务器故障

我会简单地使用已经写好的解决方案:How to deleteemptyfolders using windows Command Prompt? (我正在谈论的解决方案(所有功劳归于作者)还包含带有空格的目录):

for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
Run Code Online (Sandbox Code Playgroud)

最终的脚本将如下所示:

@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
Run Code Online (Sandbox Code Playgroud)