Вы должны войти, чтобы создавать сообщения и темы.

Батник для копирования в папку

Доброе утро! Есть батник для копирования файла в одноимённую папку. Он работает при переносе файла на батник. Но при переносе сразу нескольких файлов он выдаёт ошибку: СкопированоНедопустимое число параметров. Помогите, пожалуйста, как сделать так, чтобы батник работал сразу с несколькими файлами, то есть, чтобы копировал несколько файлов в одну папку, при этом имя создаваемой папки должно совпадать с именем файла, на котором находится курсор при переносе.
Например, аналогичным образом работает батник для создания архивов.

Спойлер

7z a "%~dpn1.7z" %*

 

xcopy %* "%~dpn1\"

 

Имир, Привет.

set "first=%~1"
set "base=%~dpn1"

if not exist "%base%" (
    mkdir "%base%"
)

for %%F in (%*) do (
    copy "%%~F" "%base%" >nul
)
Лайкнул Имир
Имир
«Любой дурак может знать. Дело в том, чтобы понять.» — Альберт Эйнштейн

Mikhail, работает! Спасибо огромное! А можно сделать так, чтобы папки тоже копировал целиком с сохранением их структуры? Сейчас если в копируемой группе элементов есть папка, то батник копирует только файлы из этой папки

set "first=%~1"
set "base=%~dpn1"

if not exist "%base%" (
    mkdir "%base%"
)

for %%F in (%*) do (
    if exist "%%~F\" (
        xcopy "%%~F" "%base%\%%~nxF\" /E /I /Y >nul
    ) else (
        copy "%%~F" "%base%" >nul
    )
)
Лайкнул Имир
Имир
«Любой дурак может знать. Дело в том, чтобы понять.» — Альберт Эйнштейн

Mikhail, идеально! Огромнейшее спасибо!

Mikhail, прошу прощения, я могу написать вот так в одну строку? Это будет корректно? Проверил — вроде бы всё по-прежнему работает

(if not exist "%~dpn1" (mkdir "%~dpn1")) & for %%F in (%*) do (if exist "%%~F\" (xcopy "%%~F" "%~dpn1\%%~nxF\" /E /I /Y >nul) else (copy "%%~F" "%~dpn1" >nul))

 

Да, норм, просто читать не удобно)

Лайкнул Имир
Имир
«Любой дурак может знать. Дело в том, чтобы понять.» — Альберт Эйнштейн

Mikhail, Привет. Работает исправно,если создать ярлык на рабочем столе и перетаскивать на него. Но я пользуюсь Тотал Коммандер, и если там использовать кнопку (путём перетаскивания в панель), то копируется только один файл (на котором курсор). Не могли бы Вы этот cmd оптимизировать для работы в Тотале.

Андрей, Привет.
Геморрой какой-то с этим total), на powershell ток получилось, более менее адекватно пока что, с этими перечислениями файлов и т.д...
Ниже код для запуска из cmd, в параметры кнопки в total вписать параметр %L, тащить файлы на кнопку не нужно, просто выделил, нажал кнопку, появится выбор имени файла, выбираем, нажимаем ок и все.

@echo off
chcp 65001 >nul
set "list=%~1"

powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "Add-Type -AssemblyName System.Windows.Forms;" ^
  "$list = Get-Content -LiteralPath '%list%';" ^
  "$form = New-Object Windows.Forms.Form;" ^
  "$form.Text = 'Выбор файла'; $form.Size = '400,120'; $form.StartPosition = 'CenterScreen';" ^
  "$combo = New-Object Windows.Forms.ComboBox;" ^
  "$combo.Location = '10,10'; $combo.Size = '360,20'; $combo.DropDownStyle = 'DropDownList';" ^
  "$combo.Items.AddRange(($list | ForEach-Object { Split-Path $_ -Leaf }));" ^
  "$form.Controls.Add($combo);" ^
  "$ok = New-Object Windows.Forms.Button;" ^
  "$ok.Text = 'OK'; $ok.Location = '150,40'; $ok.Add_Click({$form.Tag = $combo.SelectedItem; $form.Close()});" ^
  "$form.Controls.Add($ok);" ^
  "$form.ShowDialog() | Out-Null;" ^
  "$chosenLeaf = $form.Tag;" ^
  "if ($chosenLeaf) {" ^
  "  $chosen = $list | Where-Object { (Split-Path $_ -Leaf) -eq $chosenLeaf } | Select-Object -First 1;" ^
  "  $base = Join-Path (Split-Path $chosen -Parent) ([System.IO.Path]::GetFileNameWithoutExtension($chosen));" ^
  "  if (-not (Test-Path $base)) { New-Item -ItemType Directory -Path $base | Out-Null };" ^
  "  foreach ($f in $list) { if ($f -ne $chosen) { if (Test-Path $f -PathType Container) { Copy-Item -Recurse -Force $f -Destination (Join-Path $base (Split-Path $f -Leaf)) } else { Copy-Item -Force $f -Destination $base } } }" ^
  "}"
Лайкнул Андрей
Андрей
«Любой дурак может знать. Дело в том, чтобы понять.» — Альберт Эйнштейн

Mikhail, Шикарно! Спасибо Большое 👍

Mikhail, Привет. Только сейчас заметил,что в папку не попадает файл,название которого выбрано в чекбоксе. Не могли бы проверить.

Андрей, Привет. Да, косяк, проверь.

@echo off
chcp 65001 >nul
set "list=%~1"

powershell -NoProfile -ExecutionPolicy Bypass -Command ^
  "Add-Type -AssemblyName System.Windows.Forms;" ^
  "$list = Get-Content -LiteralPath '%list%';" ^
  "$form = New-Object Windows.Forms.Form;" ^
  "$form.Text = 'Выбор файла'; $form.Size = '400,120'; $form.StartPosition = 'CenterScreen';" ^
  "$combo = New-Object Windows.Forms.ComboBox;" ^
  "$combo.Location = '10,10'; $combo.Size = '360,20'; $combo.DropDownStyle = 'DropDownList';" ^
  "$combo.Items.AddRange(($list | ForEach-Object { Split-Path $_ -Leaf }));" ^
  "$form.Controls.Add($combo);" ^
  "$ok = New-Object Windows.Forms.Button;" ^
  "$ok.Text = 'OK'; $ok.Location = '150,40'; $ok.Add_Click({$form.Tag = $combo.SelectedItem; $form.Close()});" ^
  "$form.Controls.Add($ok);" ^
  "$form.ShowDialog() | Out-Null;" ^
  "$chosenLeaf = $form.Tag;" ^
  "if ($chosenLeaf) {" ^
  "  $chosen = $list | Where-Object { (Split-Path $_ -Leaf) -eq $chosenLeaf } | Select-Object -First 1;" ^
  "  $base = Join-Path (Split-Path $chosen -Parent) ([System.IO.Path]::GetFileNameWithoutExtension($chosen));" ^
  "  if (-not (Test-Path $base)) { New-Item -ItemType Directory -Path $base | Out-Null };" ^
  "  foreach ($f in $list) {" ^
  "    if (Test-Path $f -PathType Container) {" ^
  "      Copy-Item -Recurse -Force $f -Destination (Join-Path $base (Split-Path $f -Leaf))" ^
  "    } else {" ^
  "      Copy-Item -Force $f -Destination $base" ^
  "    }" ^
  "  }" ^
  "}"
Лайкнули Psydiant и Андрей
PsydiantАндрей
«Любой дурак может знать. Дело в том, чтобы понять.» — Альберт Эйнштейн

Mikhail, Отлично.