Как использовать rsync вместо цикла for в пакете - PullRequest
0 голосов
/ 24 апреля 2018

В каждой подпапке на пути 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/" 

Скрипт закрывается с синтаксической ошибкой. Можно ли использовать rsync в цикле for?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Я думаю, вы столкнулись с "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/"

Ошибка, которую вы получаете, вероятно, что-то вроде:

Источник и пункт назначения не могут быть оба удаленными.rsync error: синтаксис или ошибка использования (код 1) в 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/"
    )
)

Сценарий принимает путь к окну C:\prg\PowerShell\test\SO\test1\*а затем он использует cygpath.exe для преобразования пути в путь в стиле Unix и сохраняет его во временный файл (tmp_file.tmp).Затем он читает из временного файла путь в переменную unix %unix_path%, которая затем используется в rsync.exe.

Примечание: Как кто-то уже связал, как переместить файл с помощью rsync.Я просто укажу вариант.Вы должны добавить --remove-source-files, который удаляет файлы после передачи.

** Edit **

  • Думаю, теперь я понимаю, что вы имеете в виду.Теперь 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 или даже ошибка сервера .

Я бы просто пошел с уже написанным решением: Как удалить пустые папки с помощью командной строки Windows? (я говорю о решении (все кредиты автору), которое принимает также каталоги с пробелами):

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
0 голосов
/ 03 мая 2018

rsync может выполняться внутри цикла for.Ниже приведен пример кода для перемещения всех файлов из каталога в каталог «EXAMPLE» в том же каталоге.

#!/bin/sh for d in ~/Desktop/a/*; do rsync -rav -h --progress --checksum $d/*.* $d/EXAMPLE/ done

Сохраните вышеперечисленное в файле .sh и запустите файл.Здесь приведенный выше код пройдет через все подкаталоги в каталоге ~ / Desktop / a / и создаст каталог EXAMPLE в каждом подкаталоге и скопирует все файлы в каталог EXAMPLE.

...