gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 13:00:03 26 4
gpt4 key购买 nike

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

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

我想尝试的是使用 rsync 命令而不是 move
 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/"

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

最佳答案

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

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

我会剖析你的代码:

在这部分中,您仍处于您使用的“Windows 世界”FOR通过 U:\0012\* 循环Windows 中的路径 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/"

你得到的错误可能是这样的:

The source and destination cannot both be remote. rsync error: syntax or usage error (code 1) at main.c(1292) [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/"
)
)

该脚本采用 Window 路径 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.comunix 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

    关于batch-file - 如何使用rsync而不是批量移入for循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50002133/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com