I have the below code which gets the last modified file from "AX copy" and compares it with the last modified file in "Reflex copy". It then outputs the difference in Error.
I need the output copy to have the same name as the input file from "AX copy". I have used something to declare the file name again and assign it to the output. however I have a problem, when delcaring it in the below code, it uses the oldest file name.
Please can someone adjust the code so the output copy has the same name as the input from the "AX copy" folder. My code is:
#echo off
cd /d C:\Users\Important Structure\Development\AX copy
for /f %%a in ('dir /b /o-d /a-d /tw') do (set latest=%%a)
setlocal enableextensions disabledelayedexpansion
call :getLatestFileInFolder "C:\Users\Important Structure\Development\AX copy" latestC
call :getLatestFileInFolder "C:\Users\Important Structure\Development\Reflex copy" latestD
if not defined latestC ( echo NO File in C & exit /b )
if not defined latestD ( echo NO File in D & exit /b )
for /f "tokens=1,*" %%a in (
'diff "%latestC%" "%latestD%" ^| findstr /r /c:"^<" /c:"^>"'
) do (
>> "C:\Users\Important Structure\Development\Error\%latest%" echo(%%b
)
endlocal
exit /b
:getLatestFileInFolder folderToSearch variableToReturn
setlocal
set "folder=%~1" & if not defined folder set "folder=%cd%"
set "latest="
pushd "%folder%"
for /f "tokens=*" %%a in ('dir /b /o-d /a-d /tw 2^>nul') do (set "latest=%%~fa" & goto :latestFileFound)
:latestFileFound
popd
endlocal & set "%~2=%latest%" & goto :eof
In this line
for /f %%a in ('dir /b /o-d /a-d /tw') do (set latest=%%a)
The dir command in listing file in date descending order. On first iteration (the first file), the latest file is assigned to the variable, but for command does not stop here, and continues iterating over the rest of the files. So, at end, the variable contains the oldest file in folder.
To solve it , you can list the files in ascending date order (change /o-d to /od), or use the included subroutine
call :getLatestFileInFolder "C:\Users\Important Structure\Development\AX copy" latest
Which, as the code is working, is the same that Matt has indicated to you. %latest% is the same file that %latestC%
Why does it not work. diff command has to open the file to read, so, probably, you can not write to it while diff has it locked.
To solve it, select a temporary file (set "tempFile=%temp%\%~nx0.tmp"), write the generated diff to this temporary file and then append this temporary file to the original file (type "%tempFile%" >> "%latest%") or overwrite it if the previous content is not needed (type "%tempFile%" > "%latest%")
Related
I have 5000 .pdf files which I have to rename and to move into newly created folders, whose names are based on the original file names.
For example: original name is crf--aaa--208912--2089120010.
The folder name should be 208912 and the file name 2089120010.
Please help with the process to do so.
You might want to thy the following code snippet:
rem // Change to directory containing the files:
pushd "D:\Data" && (
rem // Retrieve matching files and iterate through them:
for /F "delims=" %%F in ('dir /B /A:-D "*--*--*--*.pdf"') do (
rem // Store name of currently iterated file:
set "NAME=%%F"
setlocal EnableDelayedExpansion
rem /* Split name into tokens separated by `--`; since `for /F` uses characters
rem as delimiters but not strings, `--` is replaced by `|` intermittently: */
for /F "tokens=3* delims=|" %%I in ("!NAME:--=|!") do (
endlocal
rem // Create sub-directory:
mkdir "%%I"
rem // Rename and move file:
move "%%F" "%%I\%%J"
)
endlocal
)
rem // Restore previous working directory:
popd
)
I have text file (2.txt) with even number of lines. Odd lines are current names of the files that I need renamed (odd lines contain file extension). Even lines are new names of the corresponding files (even lines DO NOT contain file extension).
E.g. of such file:
001.mp3
First song.
002.mp3
I am a song, too!
003.mp3
He's the one who will rename me...
(end of file)
I want to loop through file, read the line into variable, check if it contains extension (mp3). If yes (odd line), then save it to "name" variable. If not (even line), then save it to "line" variable with dot and extension added to the end (e.g., First song..mp3) and rename "name" file into "line" file. Thus "001.mp3" will be renamed to "First song..mp3".
I tried to combine different parts of the code from different sources, but something goes wrong.
FOR /F "tokens=*" %%i IN (2.txt) DO (
set var=%%i
if not x%var:mp3=%==x%var% set name=%%i
if x%var:mp3=%==x%var% (
set line=%%i.mp3
ren name line
)
)
pause
This is some tricky code. Hopefully you will understand it.
I used this as my 2.txt file
001.mp3
First song
002.mp3
I am a song
003.mp3
last song
004.mp3
my final! song
And here is my code.
#echo off
setlocal enableExtensions enableDelayedExpansion
for /F "tokens=1* delims=:" %%a in ('findstr /N "^" "2.txt"') do set "lines=%%~a"
set /a "lines=lines / 2"
< 2.txt (
for /L %%l in (1, 1, %lines%) do (
set "line1="
set "line2="
set /P "line1="
set /P "line2="
echo rename "!line1!" "!line2!.mp3"
)
)
endlocal
Pause
My output
rename "001.mp3" "First song.mp3"
rename "002.mp3" "I am a song.mp3"
rename "003.mp3" "last song.mp3"
rename "004.mp3" "my final! song.mp3"
Press any key to continue . . .
Remove the ECHO before the rename command if you feel the output on the screen looks good.
Try like this :
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in (2.txt) do (
set "$Line=%%a"
If /i [!$Line:~-4!]==[.mp3] (
set "$FileMp3=%%a"
) else (
echo ren "!$FileMp3!" "%%a.mp3"
)
)
)
If the output is correct remove the echo
I ripped my CDs with EAC to CUE+WAV files, added cover art and all my files are in the same folder with filenames pattern "Album artist - Album title", for ex.:
Clannad - Legend.wav/cue/jpg
David Bowie - Best Of Bowie [Disc 1].wav/cue/jpg
David Bowie - Best Of Bowie [Disc 2].wav/cue/jpg
I'm new to this so I wrote a simple CMD batch to convert my music to FLAC format, but it requires manual copying and pasting of the actual wav/cue/jpg filenames and input of album artist, disc no. and total disc no. for their corresponding tags. It cannot be stored in cuesheet file for some reason, but in my case I have them in filenames as you can see above).
ECHO WAV/CUE/JPG FILENAME
SET /P "input="
ECHO ALBUMARTIST
SET /P "albumartist="
ECHO DISCNUMBER
SET /P "discnumber="
ECHO TOTALDISCS
SET /P "totaldiscs="
flac.exe -0 --picture="D:\Music\%input%.jpg" --tag-from-file="CUESHEET=D:\Music\%input%.cue" -T "ALBUMARTIST=%albumartist%" -T "DISCNUMBER=%discnumber%" -T "TOTALDISCS=%totaldiscs%" "D:\Music\%input%.wav"
My question is about automation of converting all my ripped albums. How can I extract album artist/disc no./total disc no. info from filenames and loop that for every .wav file?
#ECHO OFF
SETLOCAL
SET "destdir=U:\destdir"
PUSHD "%destdir%"
:: Find all .jpgs where there is a .wav and .cue with the same name
FOR /f "delims=" %%a IN ('dir /b /a-d *.jpg') DO IF EXIST "%%~na.wav" IF EXIST "%%~na.cue" (
FOR %%b IN (input albumartist discnumber totaldiscs) DO SET "%%b="
SET "input=%%~na"
FOR /f "delims=-" %%b IN ("%%a") DO SET "albumartist=%%b"
FOR /f "tokens=2delims=[]" %%b IN ("%%a") DO SET "disc=%%b"
IF DEFINED disc (
FOR /f "tokens=1delims=[]" %%d IN ("%%a") DO FOR /f %%c IN ('dir /b "%%d[*.wav"') DO SET /a totaldiscs+=1
)
CALL :gflac
)
POPD
GOTO :EOF
:gflac
:: remove trailing spaces from INPUT
IF "%albumartist:~-1%"==" " SET "albumartist=%albumartist:~0,-1%"&GOTO gflac
:: presume default for disc and totaldiscs
IF DEFINED disc (FOR /f "tokens=2" %%d IN ("%disc%") DO SET /a disc=%%d) ELSE (SET /a disc=1)
IF NOT DEFINED totaldiscs SET /a totaldiscs=1
ECHO( flac.exe -0 --picture="D:\Music\%input%.jpg" --tag-from-file="CUESHEET=D:\Music\%input%.cue" -T "ALBUMARTIST=%albumartist%" -T "DISCNUMBER=%discnumber%" -T "TOTALDISCS=%totaldiscs%" "D:\Music\%input%.wav"
GOTO :eof
You would need to change the setting of destdir to suit your circumstances.
The above will merely echo the required flac line. I left it as you posted but set the scant test data you posted up as I interpret it (ie. there is a set of 3 files) on my U: drive.
Sadly, you've given us insufficient information. I've assumed that you need all three files to be present, and the default for totaldiscs is 1.
First, look for all .jpgs, and if there is a corresponding .wav and .cue then process for flac generation as follows:
Set input to the name part of the .jpg found
set albumartist to the first part of the filename, up to the -
get the [disc n] string if it's present
count the number of .wavs that start with the filename up to the [
generate the flac line.
Within the generation of the flac line, we strip off the trailing spaces from input, convert disc n to n or set disc to 1 (although this information may not be needed), and set the totaldiscs to 1 if it's not been calculated.
You don't say what flac produces as output, but I'd suggest that you further gate that filetype so that the procedure doesn't run if the %input%.finalproductwhateverthatis file is present.
[edited per dbenham's comments]
This is very similar to Magoo's answer, with some bug fixes, and everything is done in one master loop without a CALL. As with Magoo's answer, modify your destination folder at the beginning to suit your needs.
#echo off
:: Delayed expansion must be disabled to protect ! when expanding FOR variables.
:: It is normally disabled by default, but I'm making it explicit, just to be sure.
setlocal disableDelayedExpansion
:: Define where source files are coming from
set "source=D:\Music"
:: Define where output should be stored
set "destination=D:\Music"
pushd "%destination%"
:: Iterate each .wav file (A) and only proceed if .jpg and .cue also exists
for /f "delims=" %%A in ('dir /b /a-d "%source%\*.wav"') do if exist "%source%\%%~nA.jpg" if exist "%source%\%%~nA.cue" (
%= Get base name with path, but without extension =%
set "file=%source%\%%~nA"
%= Extract "artist - album " (B) and "Disc #" (C) from base name (~nA) =%
for /f "delims=[] tokens=1,2" %%B in ("%%~nA") do (
%= Extract "artst " (D) from "artist - abum ". (~nxD) trims trailing space =%
for /f "delims=-" %%D in ("%%B") do set "artist=%%~nxD"
%= Extract the number (E) from "Disc #", use 1 as default if not there =%
set "disc=1"
for /f "tokens=2" %%E in ("%%C") do set "disc=%%E"
%= Count the number of discs (F), will be 0 if no [Disc #] =%
%= The [ is appended to name to prevent something like "Greatest Hits 2" from matching "Greatist Hits" =%
for /f %%F in ('dir /b /a-d "%source%\%%B[*.wav" 2^>nul ^|find /c /v ""') do set "count=%%F"
%= temporarily enable delayed expansion to access variables set within loop =%
setlocal enableDelayedExpansion
%= Set count to 1 if no [Disc #] =%
if !count! equ 0 set /a count=1
flac.exe -0 --picture="!file!.jpg" --tag-from-file="CUESHEET=!file!.cue" -T "ALBUMARTIST=!artist!" -T "DISCNUMBER=!disc!" -T "TOTALDISCS=!count!" "!file!.wav"
%= pop the setlocal stack to get back to state at beginning of loop =%
endlocal
)
)
popd
You may want to add a check to only proceed if the FLAC file does not already exist so you can run the script multiple times without reprocessing files. The outer loop would look something like this, but I can't be sure since I don't know the format of the output file name:
for /f "delims=" %%A in ('dir /b /a-d "%source%\*.wav"') do if exist "%source%\%%~nA.jpg" if exist "%source%\%%~nA.cue" if not exist "%destination%\%%~nA.flac" (
The logic is much simpler using my JREPL.BAT utility if you understand regular expressions:
#echo off
:: Delayed expansion must be disabled to protect ! when expanding FOR variables.
:: It is normally disabled by default, but I'm making it explicit, just to be sure.
setlocal disableDelayedExpansion
:: Define where source files are coming from
set "source=D:\music"
:: Define where output should be stored
set "destination=D:\music"
pushd "%destination%"
:: Iterate all *.wav and use JREPL to format result as "fullFileName|artist - album|artist|Disc#"
:: %%A %%B %%C %%D
:: Only proceed if .jpg and .cue also exist
for /f "tokens=1-4 delims=|" %%A in (
'dir /b /a-d "%source%\*.wav"^|jrepl "^((.+?) - .+?)(?:\[Disc (\d+)])?\.wav$" "$&|$1|$2|$3" /i'
) do if exist "%%~nA.jpg" if exist "%%~nA.cue" (
%= disc and count are both 1 if %%D is empty =%
if "%%D" equ "" (
flac.exe -0 --picture="%source%\%%~nA.jpg" --tag-from-file="CUESHEET=%source%\%%~nA.cue" -T "ALBUMARTIST=%%C" -T "DISCNUMBER=1" -T "TOTALDISCS=1" "%source%\%%A"
%= else count the number of .wav files =%
) else for /f %%E in ('dir /b /a-d "%%B[*.wav"^|find /c /v ""') do (
flac.exe -0 --picture="%source%\%%~nA.jpg" --tag-from-file="CUESHEET=%source%\%%~nA.cue" -T "ALBUMARTIST=%%C" -T "DISCNUMBER=%%D" -T "TOTALDISCS=%%E" "%source%\%%A"
)
)
popd
Again, you can add an IF to the outer loop to proceed only if the .flac file does not already exist in the destination.
I have a lot of files that need to be joined. Existing file naming structure is 20130514ABCD.txt where the file naming convention is year, month, date, city. I would like to merge files with same last four characters (i.e same city) into one.
I am only able to move the city to a folder created for each city. This is not I want..
#echo off
pushd pathname
for /f %%F in ('dir/b/a-d *.txt') do call :sub1 %%F
goto :eof
:sub1
set name=%1
md %name:~9,12%
move %* %name:~9,12%
What I need is script equivalent to C:\>copy *CITY.TXT to CITY.txt, where CITY name is a variable.
EDITED: This works here with files as you've stated.
#echo off
pushd "pathname"
for /f "delims=" %%F in ('dir /b /a-d *.txt') do call :sub1 "%%F"
popd
pause
goto :eof
:sub1
set "name=%~1"
set "cityname=%name:~8,-4%"
if exist "%cityname%\" goto :EOF
echo processing "%cityname%"
md "%cityname%" 2>nul
copy /b "????????%cityname%.txt" "%cityname%\%cityname%.txt" >nul
this is my code:
#echo off
Setlocal EnableDelayedExpansion
set log=C:\mylog.log
set ftpFolder=C:\contributor\ftp
set rotterdamFolder=C:\rotterdam
cd /D C:\contributor
echo [FTP Folder: %ftpFolder%] >> %log%
cd /D %ftpFolder%
for /D %%f in (*) do (
cd %%f
for %%i in (*) do (
echo [FTP, %%f] Sending %%i >> %log%
for /f "tokens=1,2" %%a in (C:\input.txt) do (
if %%a==%%f (
set et=%%b
)
)
copy %ftpFolder%\%%f\%%i %rotterdamFolder%\%et% >> %log%
)
cd .. >> %log%
)
input.txt file is something like:
007 87855
008 87823
015 87830
it's not important how the two columns are divided (tab or space).
my problem is that %et% variable is not defined. how is it possible? I need to use variable "b" as destination folder. where is the error?
%et% is expanded when the line is parsed, and the entire outer parenthesized FOR loop is parsed all at once. So the value you get is the value that existed before your loop was entered.
You could solve the problem by enabling delayed expansion and using !et! instead. Type HELP FOR or FOR /? from the command line for more information. The section about delayed expansion is about halfway down.
But there really isn't any need to use the et variable at all. I believe you only want to copy the file when the first column of the inner loop matches the folder name. Simply move and substitute the COPY command for the SET statement. Use %%b instead of %et% in the COPY statement.
It wasn't necessary, but I substituted PUSHD/POPD for the CD commands. The redirection with CD is pointless when a path is specified.
You really should quote your paths in case they contain spaces or special characters.
for /D %%f in (*) do (
pushd "%%f"
for %%i in (*) do (
echo [FTP, %%f] Sending %%i >> %log%
for /f "tokens=1,2" %%a in (C:\input.txt) do if "%%a"=="%%f" (
copy "%ftpFolder%\%%f\%%i" "%rotterdamFolder%\%%b" >> %log%
)
)
popd
)