Форум программистов, компьютерный форум, киберфорум
Наши страницы
Batch (CMD/BAT)
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
Badger
91 / 91 / 4
Регистрация: 25.06.2012
Сообщений: 278
1

Соединить файлы с проверкой имени из файла

06.02.2013, 14:14. Просмотров 1123. Ответов 9
Метки нет (Все метки)

Есть файлы *.snd (много).
Из кажого файла *.snd выбираю строки, которые содержат нужный мне номер и пишу во временный файл (делается это в 5й строке, работает нормально). Дальше выбираю нужные мне токены и пихаю в переменные.
И тут проблемка: пытаюсь вывести переменные в цикле, их нет... Вне цикла, все норм, но выводит естественно только последнюю итерацию.
А суть в том, чтобы в цикле сделать проверку каждого файла (сравнение) - если в строке найдено имя первого файла в каталоге, то скопировать этот файл с именем snd.!region!. Параметр !region! содержится в каждой строке временного файла, просто проверяется при каждой итерации.
Проверять дальше - найдено имя следующего файла, а значение в переменной !region! такое же, то соединить с snd.!region! и т.д.
Bash
1
2
3
4
5
6
7
8
9
10
@echo off
setlocal enabledelayedexpansion
 
set tempfile=d:\--\temp\123\tmpfile.tmp
findstr /r /s /i /c:".*N=[0-9]*,A=[0-9]*" *.snd > %tempfile%
for /f "tokens=1,4* delims=," %%a in ('dir /b *.snd ^|findstr /i /c:"%%a" "%tempfile%"') do (
  set fName=%%a& set fName=!fName:~0,-3!& set region=%%a& set region=!region:~2!
  echo !fName! - !region!
)
echo !fName! - !region!
Хелп!

Ах да... Содержимое временного файла:
tmpfile.tmp
Код
02100001.SND:$U,U=2100,R=6503,B=6503,N=655445,A=11,S=2,L=200056987,I=0,F="Фамилия Имя Отчество",
02100002.SND:$U,U=2100,R=6503,B=6503,N=123465,A=11,S=1,L=54545,I=0,F="Фамилия Имя Отчество",
02100101.SND:$U,U=2100,R=6505,B=6505,N=678912,A=11,S=2,L=651254895,I=0,F="Фамилия Имя Отчество",
02100101.SND:$U,U=2100,R=6505,B=6505,N=345678,A=11,S=2,L=325685214,I=0,F="Фамилия Имя Отчество",
02100101.SND:$U,U=2100,R=6505,B=6505,N=912345,A=11,S=2,L=325252222,I=0,F="Фамилия Имя Отчество",
02100339.SND:$U,U=2100,R=6501,B=6501,N=654644,A=11,S=2,L=101212122,I=0,F="Фамилия Имя Отчество",
02100339.SND:$U,U=2100,R=6501,B=6501,N=258456,A=11,S=2,L=554456258,I=0,F="Фамилия Имя Отчество",
02100339.SND:$U,U=2100,R=6501,B=6501,N=201598,A=11,S=2,L=325698012,I=0,F="Фамилия Имя Отчество",
02100339.SND:$U,U=2100,R=6501,B=6501,N=654890,A=11,S=2,L=201522320,I=0,F="Фамилия Имя Отчество",
02100339.SND:$U,U=2100,R=6501,B=6501,N=115588,A=11,S=2,L=250154489,I=0,F="Фамилия Имя Отчество",
02100339.SND:$U,U=2100,R=6501,B=6501,N=999545,A=11,S=2,L=111154893,I=0,F="Фамилия Имя Отчество",
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
06.02.2013, 14:14
Ответы с готовыми решениями:

Разложить файлы по папкам с именами, являющимися частью имени файла - CMD/BAT
Привет. Помогите пожалуйста!!! Есть WIN7 папка F:\PIC в ней 4000 фото =) Файлы:...

Как можно переименовать каталог с проверкой незанятости имени?
Здравствуйте, хочу немного автоматизировать процесс работы, но столкнулся со слабым знанием...

Распределение файлов из папки по части имени файла в папки, содержащие файлы с похожим именем (квитовка)
Добрый день! Искал по форуму, но мне не удалось найти похожее решение. К примеру имеется...

Проблема с проверкой имени пользователя и пароля
пишу нечто следующее: <html> <head> <meta http-equiv='Content-Type' content='text/html;...

Как сделать проверку на наличие похожего имени файла и запрос нового имени файла?
При загрузке изображения присваивается имя foto.jpg. Вопрос, как сделать проверку на то что фото с...

9
Eva Rosalene
Ladybug
4123 / 1597 / 304
Регистрация: 06.01.2013
Сообщений: 4,191
Завершенные тесты: 2
06.02.2013, 14:29 2
Не совсем въехал
Я сейчас болею, мысли путаются, возможно просто торможу
0
Badger
91 / 91 / 4
Регистрация: 25.06.2012
Сообщений: 278
06.02.2013, 18:08  [ТС] 3
Уффф, пообедал и увидел, что перемудрил с
Bash
1
('dir /b *.snd ^|findstr /i /c:"%%a" "%tempfile%"')
Добавлено через 5 минут
Цитата Сообщение от FraidZZ Посмотреть сообщение
Не совсем въехал
Моя вина)
Присвоил токенам переменные.
Смотрим каталог... Первый встретившийся файл *.snd проверяем во временном файле (первый токен), если он найден - скопировать этот файл с именем snd.!region! (!region! - 4й токен). Если такой файл уже есть - соединить их (дабавить текст в конец файла).

Добавлено через 1 час 52 минуты
Домучал...
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@echo off
setlocal enabledelayedexpansion
 
echo.
echo Processing...
echo.
set f=
set tempfile=d:\--\temp\123\tmpfile.log
findstr /r /s /i /c:".*N=[0-9]*,A=[0-9]*" *.snd > %tempfile%
for /f %%i in ('dir /b *.snd') do (
  for /f "usebackq tokens=1,4* delims=," %%a in ("%tempfile%") do (
    set fName=%%a& set fName=!fName:~0,-3!& set region=%%b& set region=!region:~2!
    call :work "%%i" !fName! !region!
  )
  goto :eof
)
 
:work
if "%f%"=="%~2" goto :eof
>nul find /i "%~2" < "%tempfile%"&& set f=%~2&& @echo.>>snd.!region:~2!
>nul copy snd.!region:~2!+%~2
Добавлено через 1 час 40 минут
Продолжение:
Bash
1
forfiles /p %from% /m *.snd /s /c "cmd /c copy /-y @file %to%" /d 0
Заменяет файлы с совпадающими именами, как решить это?
0
Eva Rosalene
Ladybug
4123 / 1597 / 304
Регистрация: 06.01.2013
Сообщений: 4,191
Завершенные тесты: 2
06.02.2013, 18:26 4
Bash
1
2
3
for %%a IN (%from%\*.snd) DO (
 if not exist "%to%\%%a" (copy %%a %to%) else (copy %%a %to%\%%a%RANDOM%)
)
Добавлено через 1 минуту
Вероятность попадания заново в один рандом мизерно мала, но также можно решить рекурсией
0
06.02.2013, 18:26
Badger
91 / 91 / 4
Регистрация: 25.06.2012
Сообщений: 278
06.02.2013, 18:47  [ТС] 5
А как этот цикл прикрутить к forfiles?
Bash
1
forfiles /p %from% /m *.snd /s /c "cmd /c copy @file %to%" /d -7
Выборка за последние 7 дней.
0
Eva Rosalene
Ladybug
4123 / 1597 / 304
Регистрация: 06.01.2013
Сообщений: 4,191
Завершенные тесты: 2
06.02.2013, 19:13 6
Написать функцию.
В конец файла добавить
Код
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
exit /b
:copy
set filename=%~1
set foldername=%~2
set string=%~3
if "!string!"=="" (set string=1)
set /a string=!string!
set nextstring=!string!+1
if not "!foldername:~-1!"=="\" (
 if not exist "%~dpn2!string!%~x2" (
  copy "!filename!" "%~dpn2!string!%~x2"
 ) else (call :copy "%~1" "%~2" !nextstring!)
) else (
 if not exist "!foldername!%~1" (
  copy "%~1" "%~2"
 ) else (call :copy "%~1" "%~2" !nextstring!)
)
exit /b

Параметр ♦setlocal enabledelayedexpansion должен быть включен

Добавлено через 51 секунду
Ну и вызывать "call :copy" с синтаксисом, как у обычной "copy"
1
Badger
91 / 91 / 4
Регистрация: 25.06.2012
Сообщений: 278
07.02.2013, 10:31  [ТС] 7
Жжжесть
Завтра попробую прикрутить, спасибо.

Добавлено через 12 часов 14 минут
Что то не смог прилепить функцию к forfiles. Ошибка попытки перехода по метке.
Код сейчас имеет такой вид без функции и без переименования одинаковых файлов, которые необходимо сделать:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@echo off
setlocal enabledelayedexpansion
 
set f=
set tempfile=d:\temp\tmpfile.log
set from=t:\post2013
set to=d:\temp
 
echo Поиск и копирование *.snd файлов в архиве за N последних дней
echo.
>nul forfiles /p %from% /m *.snd /s /c "cmd /c copy @file %to%" /d 0
echo Формирование временного файла
echo.
findstr /r /s /i /c:".*N=[0-9]*,A=[0-9]*" *.snd > %tempfile%
echo Группировка файлов.
echo.
for /f %%i in ('dir /b *.snd') do (
  for /f "usebackq tokens=1,4* delims=," %%a in ("%tempfile%") do (
    set fName=%%a& set fName=!fName:~0,-3!& set region=%%b& set region=!region:~2!
    call :work "%%i" !fName! !region!
  )
  del /f /q %to%\*.snd
  del /f /q %tempfile%
  pause>nul
  goto :eof
)
 
:work
if "%f%"=="%~2" goto :eof
>nul find /i "%~2" < "%tempfile%"&& set f=%~2&& @echo.>>snd.!region:~2!
>nul copy snd.!region:~2!+%~2
0
Dragokas
Эксперт WindowsАвтор FAQ
17081 / 7136 / 861
Регистрация: 25.12.2011
Сообщений: 10,945
Записей в блоге: 16
07.02.2013, 16:22 8
Не вижу, чтобы код совпадал с техзаданием. По коду ничего не понятно.
Что вообще такое "первый файл" - по какому критерию ???

Чем вообще отличается этот кусок кода:
1) ... %%a in ("%tempfile%") do (
...set fName=%%a
call :work "%%i" !fName!...
от
2) >nul find /i "%~2"
...Вы сначала взяли с файла, а потом проверили, что оно там было (это ж тоже самое).
Может там не %~2, а %~1 должна быть.

Bash
call :work "%%i" !fName! !region!
передается 3 параметра, а используется только %~2 ???

for /f %%i in ('dir /b *.snd') do (
for...
зачем вложенный цикл? - путает всю логику.
Разве нельзя написать так:
Bash
1
2
for /f %%i in ('dir /b *.snd') do Set firstfile=%%i& goto :ext
:ext
Цитата Сообщение от Badger Посмотреть сообщение
Ошибка попытки перехода по метке.
Такая ошибка бывает, когда файл сохранен в UNIX-формате (ошибка № 4). Выход: создать новый текстовой файл (обычным способом -> пкм - > Создать), перенести код туда.
0
Badger
91 / 91 / 4
Регистрация: 25.06.2012
Сообщений: 278
07.02.2013, 17:32  [ТС] 9
Цитата Сообщение от Dragokas Посмотреть сообщение
Не вижу, чтобы код совпадал с техзаданием.
Цитата Сообщение от Badger Посмотреть сообщение
И тут проблемка: пытаюсь вывести переменные в цикле, их нет...
Это была первоначальная проблема, позже решил сделать по другому, но смысл темы остался тот же.
Цитата Сообщение от Dragokas Посмотреть сообщение
Чем вообще отличается
Они делают 2 разные задачи: 1й кусок - присваивает переменным значениям, если найдено совпадение файлов в каталоге и временном файле. 2й кусок - пропускает повторяющиеся строки во временном файле (в нем могут быть достаточно много повторений с именем файла).
Цитата Сообщение от Dragokas Посмотреть сообщение
передается 3 параметра, а используется только %~2 ???
Да здесь перемудрил... Можно оставить последние 2.
Цитата Сообщение от Dragokas Посмотреть сообщение
зачем вложенный цикл? - путает всю логику.
Что бы привести в соответствие файлов в каталоге с файлами во временном файле.
Нужно пересмотреть... :-\

Добавлено через 14 минут
Ех... Почему то мне кажется, что я всех только больше запутал:)
В общем задание таково:
1. Найти файлы *.snd по всем районам за последние N дней, которые находятся в каталоге t:\post2013\район\месяц\день\ (имена могут совпадать, можно добавить или изменить любой символ в имени).
2. Соединить содержимое этих файлов порайонно в каждый файл по отдельности (районы 6501-6523).
Как то так.
0
Dragokas
Эксперт WindowsАвтор FAQ
17081 / 7136 / 861
Регистрация: 25.12.2011
Сообщений: 10,945
Записей в блоге: 16
11.02.2013, 00:06 10
Badger, много чего непонятного.
Да сейчас тоже вот болею. И не соображу.
Вы вроде как тоже хорошо кодите.

Вот моя подсказка к 3-му посту:
Bash
1
2
del tmpfile.txt
forfiles /p "%from%" /m *.snd /s /c "cmd /c echo @file>>tmpfile.txt" /d 0
А дальше циклом обрабатываете файл tmpfile.txt
Там можете уже крутить что угодно. Проверки совпадений, if exist...

Добавлено через 25 минут
В этой теме
функция для получения нового имени файла, если в целевом каталоге такой уже существует.
1
11.02.2013, 00:06
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.02.2013, 00:06

Сделать проверку на наличие похожего имени файла и запрос нового имени файла
Пользователь задает имя для создания файла. Вопрос, как сделать проверку на наличие похожего имени...

Соединить несколько текстовых файлов в один с указанием имени каждого
Написать программу,которая из всех текстовых файлов в каталога формирует один большой текстовый...

Получение данных из файла с проверкой даты изменения файла
Скрипт, который получит данные их файла (get-content -File &quot;C:\File.txt&quot; в файле написано число),...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru