I want to solve one question about path.
I have this code take in this forum who separetes stereo files in 2 mono files:
#ECHO OFF
SETLOCAL
for %%n in (*.wav) do CALL :runsox "%%n"
GOTO :eof
:runsox
CALL :wait
START "%~1.left" C:\sox\sox.exe %~1 -c 1 %~1.left.flac remix 1
CALL :wait
START "%~1.right" C:\sox\sox.exe %~1 -c 2 %~1.right.flac remix 2
GOTO :eof
:wait
FOR /f %%c IN ('tasklist^|find /i /c "sox.exe"') DO SET running=%%c
IF %running% GEQ 6 timeout /t 5 >nul&GOTO wait
GOTO :eof
but I want know how is possible make a little mod to move lefts file on a subfolder eg. /left and right files in /right in the main code without needed execute other batch:
I did that in a separete batch:
move *.wav.left.wav left/
move *.wav.left.wav right/
#echo off
setlocal enableextensions disabledelayedexpansion
2>nul (
md right
md left
)
for %%a in (*.wav) do (
call :wait
start "%%~na.left" C:\sox\sox.exe "%%~fa" -c 1 "%%~dpa\left\%%~na.left.flac" remix 1
call :wait
start "%%~na.right" C:\sox\sox.exe "%%~fa" -c 2 "%%~dpa\right\%%~na.right.flac" remix 2
)
goto :eof
:wait
FOR /f "skip=4 tokens=5 delims=," %%p IN ('
tasklist /fo:csv /nh /fi "imagename eq sox.exe"
') do ( >nul timeout /t 5 & goto :wait )
GOTO :eof
The for replaceable parameter %%a will hold the reference to the file being processed, so we can use this reference to obtain partial information (see for /? for the full list)
%%~na is the name of the file without extension
%%~fa is the full path to the file
%%~dpa is the drive and path where the file is stored
Using the indicated elements, command is changed to include the output folder.
Related
I have some PDF files that I need to rename and move to specific folders to be able to import into a system.
The file by default has the following name:
ex: 12345.123456/1234-12.pdf
First I need to remove the characters "," "/" "-"
#echo off
setlocal EnabledelayedExpansion
for /r "C:\importation" %%a in (*) do (
set "newname=%%~na"
set "newname=!newname:.=!"
set "newname=!newname:-=!"
set "newname=!newname:/=!"
ren "%%~a" "!newname!%%~xa"
)
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern:
ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001_Volume.pdf
For that I drag the files to the following script:
#If Not "%~1" == "" For %%G In (%*) Do #MD "%%~dpG%%~nG" 2>NUL && Move /Y "%%~G" "%%~dpG%%~nG\P%%~nG_V1_A0V0_T07-54-369-664_S00001_Volume%%~xG"
I would like to do only one process, that is, join the two scripts and run only once.
Can someone help me?
Rather than dragging the files to the batch file I would like to run it and have it read the files (.pdf) from the folder
Is something like this what you are looking for?
The following will accept drag and drop of one or more files or directories, (subject to command line length restrictions). Each individually dropped PDF file and each PDF file within any dropped directory should be processed as requested.
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
Please note, as the character / is invalid in file or directory names, I have ignored that part of your question.
I have some pdf's in a folder that I need to organize them like this:
PDF name: 123.12.123.pdf ; 102030_01.pdf; 102030_02.pdf; 123.4512.34561.23412.pdf
Now I need to create folders with the filename (without the characters removed, ex: 12345123456123412) and rename them to the following pattern: ex: P12345123456123412_V1_A0V0_T07-54-369-664_S00001.pdf
for this I have used the following code which works very well:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
If "%~1" == "" GoTo :EOF
For %%G In (%*) Do (For %%H In ("%%~G") Do If "%%~aH" Lss "-" (
Echo Error! %%G no longer exists.
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL
) Else If "%%~aH" GEq "d" (For %%I In ("%%~G\*.pdf") Do Call :Sub "%%~I"
) Else If /I "%%~xG" == ".pdf" (Call :Sub "%%~G"
) Else (Echo Error! %%G is not a PDF
%SystemRoot%\System32\timeout.exe /T 2 /NoBreak 1>NUL))
GoTo :EOF
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
I drag the pdfs into the .bat and it does the adjustment.
It happens that there is a case that I am not able to handle. Some pdfs need to be in the same folder, for example in the following case:
PDF name: 102030_01.pdf; 102030_02.pdf;
Note that the pdfs have the same number, only after the _ that we have the difference. In this case you would need to create a folder with the name:102030
And move the two files into it, modifying their name as follows:
102030_01.pdf -> P102030_V1_A0V0_T07-54-369-664_S00001.pdf
102030_02.pdf -> P102030_V1_A0V0_T07-54-369-664_S00002.pdf
Could anyone help?
:Sub
Set "basename=%~n1"
Set "basename=%basename:.=%"
if /i "%basename%" neq "%basename:_=%" goto sub2
MD "%~dp1%~n1" 2>NUL
If Not ErrorLevel 1 Move /Y %1 "%~dp1%~n1\P%basename:-=%_V1_A0V0_T07-54-369-664_S00001_Volume%~x1"
Exit /B
:sub2
for /f "tokens=1*delims=_" %%b in ("%basename%") do (
MD "%~dp1%%b" 2>NUL
ECHO Move /Y %1 "%~dp1%%b\P%basename:-=%_V1_A0V0_T07-54-369-664_S000%%c_Volume%~x1"
)
Exit /B
Always test on dummy data first.
This code echoes the proposed move. After verification, remove the echo keyword to activate.
Caution: My reading of the code is that - should be removed from the basename in the new name, and that _Volume should be appended to the name part, which is not shown in your examples.
Essentially, if the basename contains _ then goto sub2.
sub2 partitions the name in basename, assigning the first part to %%b and the second to %%c (See for /? from the prompt for documentation)
Then the directory is created
The md will object if the directory already exists, hence the 2>nul in the original code (suppresses error messages)
If md found that error in the original then this appears to be a problem, so the move is not executed. In the new version, it is expected that the directory may already exist, so the errorlevel processing has been removed.
I have a batch to check the duplicate line in TXT file (over one million line) with 13MB, that will be running over 2hr...how can I speed up that? Thank you!!
TXT file
11
22
33
44
.
.
.
44 (over one million line)
Existing Batch
setlocal
set var1=*
sort original.txt>sort.txt
for /f %%a in ('type sort.txt') do (call :run %%a)
goto :end
:run
if %1==%var1% echo %1>>duplicate.txt
set var1=%1
goto :eof
:end
This should be the fastest method using a Batch file:
#echo off
setlocal EnableDelayedExpansion
set var1=*
sort original.txt>sort.txt
(for /f %%a in (sort.txt) do (
if "%%a" == "!var1!" (
echo %%a
) else (
set "var1=%%a"
)
)) >duplicate.txt
This method use findstr command as in aschipfl's answer, but in this case each line and its duplicates are removed from the file after being revised by findstr. This method could be faster if the number of duplicates in the file is high; otherwise it will be slower because the high volume data manipulated in each turn. Just a test may confirm this point...
#echo off
setlocal EnableDelayedExpansion
del duplicate.txt 2>NUL
copy /Y original.txt input.txt > NUL
:nextTurn
for %%a in (input.txt) do if %%~Za equ 0 goto end
< input.txt (
set /P "line="
findstr /X /C:"!line!"
find /V "!line!" > output.txt
) >> duplicate.txt
move /Y output.txt input.txt > NUL
goto nextTurn
:end
#echo off
setlocal enabledelayedexpansion
set var1=*
(
for /f %%a in ('sort q42574625.txt') do (
if "%%a"=="!var1!" echo %%a
set "var1=%%a"
)
)>"u:\q42574625_2.txt"
GOTO :EOF
This may be faster - I don't have your file to test against
I used a file named q42574625.txt containing some dummy data for my testing.
It's not clear whether you want only one instance of a duplicate line or not. Your code would produce 5 "duplicate" lines if there were 6 identical lines in the source file.
Here's a version which will report each duplicated line only once:
#echo off
setlocal enabledelayedexpansion
set var1=*
set var2=*
(
for /f %%a in ('sort q42574625.txt') do (
if "%%a"=="!var1!" IF "!var2!" neq "%%a" echo %%a&SET "var2=%%a"
set "var1=%%a"
)
)>"u:\q42574625.txt"
GOTO :EOF
Supposing you provide the text file as the first command line argument, you could try the following:
#echo off
for /F "usebackq delims=" %%L in ("%~1") do (
for /F "delims=" %%K in ('
findstr /X /C:"%%L" "%~1" ^| find /C /V ""
') do (
if %%K GTR 1 echo %%L
)
)
This returns all duplicate lines, but multiple times each, namely as often as each occurs in the file.
I have a folder with 110.000 files and I want a way to break this folder into multiple subfolders containing say 3000 files each (with a batch script perhaps?). (Trying a copy/paste with WinExplorer gets stuck in "Preparing to Copy".)
For example:
BigFolder
|
NewFolder
| | | | |
Sub1 Sub2 Sub3 Sub4 Sub5...
I am surprised to find the same case of mine.
I had 30,000 files that needed to be sorted, so I asked question on this page:
Fast methods to copy(move) files in batch file
This is Compo's script:
#Echo Off
If /I Not "%__CD__%"=="%~dp0" PushD "%~dp0" 2>Nul||Exit/B
SetLocal EnableDelayedExpansion
Set "DirN=-1"
:Check_DirN
Set/A "DirN+=1"
If Exist "%DirN%" GoTo Check_DirN
Set "limit=700"
For %%A In (*.bat *.cmd *.txt) Do (
If Not Exist "%DirN%" MD "%DirN%"
If /I Not "%%~nxA"=="%~nx0" RoboCopy . "%DirN%" "%%A" /MOV 1>NUL
Set/A "limit-=1"
If !limit! Lss 0 GoTo Check_DirN
)
Echo(Task Done!
Timeout -1 1>Nul
And this is what I use and I edited for a bit for the purpose:
#Echo Off
If /I Not "%__CD__%"=="%~dp0" PushD "%~dp0" 2>Nul||Exit/B
taskkill /f /im explorer.exe >nul
taskkill /f /im SearchIndexer.exe >nul
sc stop WSearch >nul
sc config WSearch start= disabled >nul
SetLocal EnableDelayedExpansion
Set "DirN=-1"
:Check_DirN
Set/A "DirN+=1"
If Exist "%DirN%" GoTo Check_DirN
cls
echo Moving files to Directory %DirN%...
Set "limit=2999"
MD "%DirN%"
For %%A In (*.html) Do (
RoboCopy . "%DirN%" "%%A" /MOV 1>NUL
Set/A "limit-=1"
If !limit! Lss 0 GoTo Check_DirN
)
Echo(Task Done!
start explorer.exe
start SearchIndexer.exe
sc config WSearch start= delayed-auto >nul
sc start WSearch >nul
Timeout -1 1>Nul
You can remove taskkill, start and sc part if desired.
I added this part because explorer and Windows Search Indexer will cause waste of memory when moving files. I recommend you to run the script with Administrator privilege.
Try to test the script in small scale to see if it does work.
I have a directory that contains close to a million XML files. Needless to say, it takes forever to load (20+ minutes) So, I'm writing a script to divide the files into folders with the top level being year and having months under each year. There are 4 main filenames where the date can be extracted from the 3rd token and the rest from the second token. ie:
BA1253570001_BALMIS_20130617_TRC_0_109506738E.xml
BA1254260001_ACCTV21_20140430_AMR_0_1095611492.xml
BA1736330001_SWFTOUT_20140929_LIQ_1_MTBX553494.xml
BA1739240001_FEDOUT_20140904_LIQ_1_105633316M.xml
The rest are like this:
EODMESS_20140718_MTBX473286.xml
MSGCONF_20140410_109558667V.xml
I'm sure there is an easier way to do it, but here is my code so far:
#echo on
setlocal enabledelayedexpansion
Set "starttime=%time%"
pushd C:\temp\xmls
for /f %%a in ('dir /b/o:d *.xml') do (
call :ExtractDates %%a ret
echo %%a - !ret!
for /f "tokens=1" %%b in ("!ret!") do (
for /f "tokens=1-3 delims=/" %%c in ("%%b") do (
if not exist .\%%e md .\%%e
if not exist .\%%e\%%c md .\%%e\%%c
if %%b equ %%c/%%d/%%e (
echo moving %%~nxa to .\%%e\%%c
echo move %%~nxa .\%%e\%%c
pause
)
)
)
)
echo Start time: %starttime%
echo End time: %time%
popd
exit /b
:ExtractDates
#echo on
setlocal enabledelayedexpansion
Echo Starting ExtractDates
for %%a in (BALMIS ACCTV21 FEDOUT SWFTOUT) do (
if not errorlevel 1 (set t=3) else set t=2
Call :ExtractFunc %~1 %%a !t! ret
endlocal&set "%~2=!ret!"&exit /b 0
)
exit /b
:ExtractFunc
#echo on
setlocal
Echo Starting ExtractFunc
for /f "tokens=%3 delims=_" %%a in (
'echo %~1^|Findstr "%~2"'
) do (
if not errorlevel 1 (
endlocal&set "%~4=%%a"&exit /b 0
)
)
exit /b
The problem is that the variable token isn't returning the right number and I'm not sure why. Any suggestions appreciated.
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
PUSHD "%sourcedir%"
FOR /f "tokens=1*delims=" %%a IN (
'dir /b /a-d "%sourcedir%\*_*_*.xml" '
) DO SET "filename=%%a"&CALL :process
POPD
GOTO :EOF
:process
FOR /f "tokens=2,3,6delims=_" %%m IN ("%filename%") DO SET "date1=%%m"&SET "date2=%%n"&SET "whichdate=%%o"
IF DEFINED whichdate SET "date1=%date2%"
IF NOT DEFINED date2 GOTO :eof
ECHO(MD .\%date1:~0,4%\%date1:~4,2%
ECHO(MOVE "%filename%" .\%date1:~0,4%\%date1:~4,2%\
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
The required MD commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MD to MD to actually create the directories. Append 2>nul to suppress error messages (eg. when the directory already exists)
The required MOVE commands are merely ECHOed for testing purposes. After you've verified that the commands are correct, change ECHO(MOVE to MOVE to actually move the files. Append >nul to suppress report messages (eg. 1 file moved)
Simply extract the two possible datestrings and use the presence of the sixth token to signal which of the two positions to select for generation of the destination directory. Skip if there's no third token (fails to fit mask specified)
Then select the required field to date1 and do some substringing.