Need to run GPSBabel command on txt files - windows

I'm using windows 10. My current project requires me to merge several TXT files into a single one. Problem is that the TXT files has all the same name and what differentiate them is their folder name.
For example:
Folder1
Folder with a 13 digits random name
gpsdata.txt
Folder with a 13 digits random name
gpsdata.txt
- Folder with a 13 digits random name
gpsdata.txt
I tried using the following BATCH command but it overwrites the file and I end with only the track from the last gpsdata.txt file.
FOR /R C:\FOLDER1 %%i IN (metadata.txt) DO X:\GPSBabel\gpsbabel -t
-i xcsv,style=C:\mystyle.style -f %%i -o gpx -F C:\FOLDER2\gpsdata.gpx
Is there a way to 'copy and merge' these txt files and transform then into gpx via .BAT using GPSBabel?
thanks

The FOR loop does not seem to be producing what you want. Try constructing the FOR loop alone until %%i comes out as you expect.
FOR /R C:\FOLDER1 %%i IN (metadata.txt) DO (ECHO %%~i)
You might want the FOR loop to produce a path to every metadata.txt file. Does this produce what you are seeking?
FOR /F "delims=" %%i IN ('DIR /S /B C:\FOLDER1\metadata.txt') DO (echo %%i)
That might make the code look like:
FOR /F "delims=" %%i IN ('DIR /S /B "C:\FOLDER1\metadata.txt"') DO (
X:\GPSBabel\gpsbabel -t -i xcsv,style=C:\mystyle.style -f "%%~i" -o gpx -F C:\FOLDER2\gpsdata.gpx
)

Do not use for /R, neither do use for /F with dir /S, since you have got a flat directory structure. What you need is for /D, or for /F together with dir in order to control sorting.
Approach using for /D (sub-directories are iterated in the order as returned by the file system):
rem // Prepare an empty file to begin with:
copy nul "C:\FOLDER1\metadata.txt" > nul
rem // Iterate over the immediate sub-directories:
for /D %%I in ("C:\FOLDER1\?????????????") do (
rem // Check whether the current sub-directory contains the text file:
if exist "%%~I\gpsdata.txt" (
rem // Append the text file to the result file:
copy /B "C:\FOLDER1\metadata.txt" + "%%~I\gpsdata.txt" "C:\FOLDER1\metadata.txt" > nul
)
)
Approach using for /F and dir (sub-directories are sorted in alphabetic manner due to /O:N):
rem // Change into target directory:
pushd "C:\FOLDER1" && (
rem // Prepare an empty file to begin with:
copy nul "metadata.txt" > nul
rem // Iterate over the immediate sub-directories:
for /F "delims=" %%I in ('dir /B /A:D-L-H-S /O:N "?????????????"') do (
rem // Check whether the current sub-directory contains the text file:
if exist "%%I\gpsdata.txt" (
rem // Append the text file to the result file:
copy /B "metadata.txt" + "%%I\gpsdata.txt" "metadata.txt" > nul
)
)
rem // Return from target directory:
popd
)

For those that may need to convert using GPSBabel on several txt files with the same name inside different subfolders to get a GPX out of them, I was able to perform this with the following batch file:
setlocal enabledelayedexpansion
FOR /F "delims=" %%i IN ('DIR /S /B C:\FOLDER1\metadata.txt') DO "X:\GPSBabel\gpsbabel.exe" -t -i xcsv,style=C:\mystyle.style -f "%%i" -x discard,hdop=10,vdop=20 -x duplicate,location -x simplify,crosstrack,error=0.001k -o gpx -F "%%i".gpx
set f=
for /F "delims=" %%f IN ('DIR /S /B C:\FOLDER1\*.gpx') DO set f=!f! -f "%%f"
"X:\GPSBabel\gpsbabel.exe" -t -i gpx %f% -x discard,hdop=10,vdop=20 -x duplicate,location -x simplify,crosstrack,error=0.001k -x nuketypes,waypoints -o gpx -F C:\FOLDER2\%DATE:~6,4%_%DATE:~3,2%_%DATE:~0,2%_LOG.gpx
The first part just create a GPX file for every TXT file inside their same folder.
The second part is taking all those GPX file and merging them into a single one on a different folder setting the name of the file as "current_date"_log.gpx

Related

How to exclude file extensions in the output filelist.txt, within a batch "dir" script in CMD

I am a CMD newbie and have a question with a batch script I am working on.
I have a parent directory with 30 sub-directories containing .pdf files, and I need a filelist.txt for each sub-directory, and have each filelist.txt save as the file name of the sub-directory it belongs too. This has been completed with the script below:
#echo off
cd /d "C:\Desktop\parentDir"
for /d %%a in (*) do (
DIR /B /ON /A-D "%%a" > %%a.txt.
move %%a.txt "%%a" >nul
)
My question is how, can I remove file extensions in the output of each filelist.txt. For ex. when I run the script now, the output .txt file shows 1111.pdf
1112.pdf
I need the ".pdf" removed
I know with a "for" command you can "do" echo %%~na to remove file extensions, but I have no clue how/where to factor this into the current script.
Any help is appreciated!
You are using DIR command to list all files. It does not have a switch to hide extension.
You can replace the DIR command with a FOR loop, like you pointed out.
cd /d "C:\Desktop\parentDir"
for /d %%a in (*) do (
for %%f in ("%%a\*") do #echo %%~nf >> %%a.txt.
move %%a.txt "%%a" >nul
)

Batch file to find and copy the latest file

There is a system that generates a txt file dump every 15 minutes with a different file name each time. I need to find the latest file containing the text 'ASN' and copy it to a folder where I can work on it.
so far I have this, but I cannot get it to copy any file.
SET smart_server='Z:\JUL2017'
FOR /F "delims=|" %%I IN ('DIR "%smart_server%" /S /B /O:D ^| find /i "ASN" ') DO SET NewestFile=%%I
copy "%smart_server%\%NewestFile%" "C:\htdocs\smart_asn_downloads\new"
The source directory is a mapped drive I'm looking to copy it to a local drive.
The following will copy the files that contains the text ASN ignoring the case in the file itself not the file name:
#echo off
set "smart_server=Z:\JUL2017"
rem list all files (recursive) latest first
for /F "delims=|" %%I in ('dir "%smart_server%" /S /B /A-D /O:-D') do (
find /i "ASN" "%%I" > nul
rem success (errorlevel == 0)?
if not errorlevel 1 (
set "NewestFile=%%I"
)
)
if defined NewestFile (
rem addionally echoing the command due copy is not verbose
echo copy "%NewestFile%" "C:\htdocs\smart_asn_downloads\new"
copy "%NewestFile%" "C:\htdocs\smart_asn_downloads\new"
) else (
echo Found no file!
)
There are several things I've changed.
1.
set:
I changed the setting of the variable smart_server because your set contains the ' in the path.
2.
The dir command:
The sorting with /O:D would show the oldest first to reverse the list use: /O:-D. Further exclude directories to show with dir because you can't search in them with find, use: /A-D.
3.
The pipe to find:
It seems that the pipe to find does not work with spaces in a filename therefore I cut it out of the command and do it in the for loop. If the find is successful I set the NewestFile variable. I use find with /I so it ignores the case of the text.
If you need the script to copy files that contain ASN in the file name itself and ends with .txt you can use (this also ignores the case):
#echo off
set "smart_server=Z:\JUL2017"
for /F "delims=|" %%I IN ('DIR "%smart_server%\*ASN*.txt" /S /B /A-D /O:-D') DO SET NewestFile=%%I
echo copy "%NewestFile%" "C:\htdocs\smart_asn_downloads\new"
copy "%NewestFile%" "C:\htdocs\smart_asn_downloads\new"

Batch: Looping through folders and subfolders and get them into a script

I want to convert .flac files from X:\Music\flac\flacfolder\name.flac to X:\Music\mp3\flacfolder\name.mp3 using ffmpeg, but I couldn't find how to loop through while passing the directory to a different command and manipulating it.
Usually, to process files recursively, I would suggest to use the for /R loop. However, in this situation, since I guess you want to copy the directory hierarchy from the source to the target folder, I do not use it, because it resolves to absolute paths only. Instead I use xcopy /L, which does not copy anything (due to /L), but lists all applicable items as paths relative to the source folder; then I wrap around a for /F loop to read the list of relative paths and to resolve them related to the target folder; in the loop body finally, the ffmpeg needs to be placed (define the options to your needs and remove the preceding upper-case ECHO after having tested; the ffmpeg tool does not receive any relative paths but absolute ones only for both input and output files):
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=X:\Music\flac\flacfolder" & rem // (absolute source path)
set "_TARGET=X:\Music\mp3\flacfolder" & rem // (absolute target path)
set "_PATTERN=*.flac" & rem // (pure file pattern for input files)
set "_FILEEXT=.mp3" & rem // (pure file extension of output files)
pushd "%_TARGET%" || exit /B 1
for /F "delims=" %%F in ('
cd /D "%_SOURCE%" ^&^& ^(rem/ list but do not copy: ^
^& xcopy /L /S /Y /I ".\%_PATTERN%" "%_TARGET%" ^
^| find ".\" ^& rem/ remove summary line;
^)
') do (
2> nul mkdir "%%~dpF."
rem // Set up the correct `ffmpeg` command line here:
ECHO ffmpeg -i "%_SOURCE%\%%~F" "%%~dpnF%_FILEEXT%"
)
popd
endlocal
exit /B
If you want the destination files in a flat folder structure instead, a for /R loop workes fine:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_SOURCE=X:\Music\flac\flacfolder" & rem // (absolute source path)
set "_TARGET=X:\Music\mp3\flacfolder" & rem // (absolute target path)
set "_PATTERN=*.flac" & rem // (pure file pattern for input files)
set "_FILEEXT=.mp3" & rem // (pure file extension of output files)
for /R "%_SOURCE%" %%F in ("%_PATTERN%") do (
rem // Set up the correct `ffmpeg` command line here:
ECHO ffmpeg -i "%_SOURCE%\%%~F" "%_TARGET%\%%~nF%_FILEEXT%"
)
endlocal
exit /B
Try something like:
#echo off
setlocal
set FLAC_FOLDER=c:\temp\flacfolder
set MP3_ROOT_FOLDER=c:\temp\mp3folder
echo Processing folder [%FLAC_FOLDER%]...
for /f "tokens=*" %%F in ('dir "%FLAC_FOLDER%\*.flac" /a-d /b') do call :PROCESS_FLAC_FILE "%FLAC_FOLDER%" "%%F"
goto END
:PROCESS_FLAC_FILE
set PFF_FOLDER=%1
set PFF_FILE=%2
set PFF_FOLDER=%PFF_FOLDER:"=%
set PFF_FILE=%PFF_FILE:"=%
for /f %%I in ("%PFF_FILE%") do set PFF_MP3_FILE=%%~nI.mp3
echo Processing FLAC file [%PFF_FILE%] in folder [%PFF_FOLDER%]; output file is [%PFF_MP3_FILE%]...
REM Now call ffmpeg using the approriate variables. Enclose the variables in double-quotes, e.g.:
REM (note, I don't know the syntax for ffmpeg, so I'm making this up as an example)
ffmpeg.exe -source "%PFF_FOLDER%\%PFF_FILE%" -target "%MP3_ROOT_FOLDER%\%PFF_MP3_FILE%"
goto END
:END
I have an example I used in the past. I tried adding your structure to it.
#echo off
cd X:\Music\flac\flacfolder
for /F "tokens=1 delims=" %%i IN ('dir /s /b ^| findstr .flac') do (
call :process_code "%%i"
)
goto end
:process_code
echo Running conversion for %1
:: Run your process here
goto :eof
:end
echo done!
I hope this helps

List all files with 2 timestamps, size, but without path or dir

Windows, Command Prompt, need to generate a .txt file output containing of all files from a big and complex dir tree with one (1) line for each files as:
CreationDateYYYYMMDD-HHMMSS, LastModifiedYYYYMMDD-HHMMSS, filesize[no K commas], filename.ext
for example:
20100101-174503, 20120202-191536, 1589567, myfile.ext
The list should not contain lines of dir name entries, etc., only filenames, even if the same file is present in more than once. Time in 24 hours format.
dir /s/t:c/t:w/-c > filelist.txt
command does not exactly works this way.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "sourcedir=c:\program files"
FOR /f "delims=" %%a IN (
'dir /s /b /a-d "%sourcedir%\*" '
) DO (
FOR %%d IN (timewritten timecreated) DO SET "%%d="
FOR %%k IN (-d s h) DO (
IF NOT DEFINED timewritten FOR /f "tokens=1,2 delims= " %%d IN ('dir /tw %%~k "%%a" 2^>nul ^|find "%%~nxa"') DO SET "timewritten=%%d %%e"
IF NOT DEFINED timecreated FOR /f "tokens=1,2 delims= " %%d IN ('dir /tc %%~k "%%a" 2^>nul ^|find "%%~nxa"') DO SET "timecreated=%%d %%e"
)
ECHO !timecreated! !timewritten! %%~za %%~nxa
)
)
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
Interesting problem. This code processes it by
First, applying the standard directory-list for filenames on the tree from the relative root (%sourcedir%) to %%a
Using the full filename in %%a, set timewritten and timecreated from an ordinary dir list targeting the file in question.
It appeared that %%~ta didn't play nicely to extract the timestamp for hidden and system files, so I decided to build them from the ordinary dir listing with the appropriate t setting, specifically listing with /a-d, /as and /ah and filtering for the line which matched the filename, which seemed to extract the data appropriately.
I left the date/time in raw format. It should be an easy task to extract the various elements and construct the report in the format you want.
This question is a dupe of the SO post cmd dir /b/s plus date, but posting what worked for me:
#echo off
REM list files with timestamp
REM Filename first then timestamp
for /R %I in (*.*) do #echo %~dpnxI %~tI
#echo off
REM list files with timestamp
REM Timestamp first then name
for /R %I in (*.*) do #echo %~tI %~dpnxI
The above are the versions that you would directly paste into a command prompt.
If you want to use these in a batch file and log the output, you could do something like:
rem: Place the following in a batch file such as DirectoriesBareWithTS.cmd.
rem: As the first step in the batch file, net use to the directory or share you want the listing of
rem: Change to your target directory
Y:
for /R %%I in (*.mp4) do #echo %%~tI %%~dpnxI
Then you can pipe the output to a log file when you execute:
DirectoriesBareWithTS.cmd > C:\temp\GiantLongDirListing.log
You could then import that log into Excel.

Batch script listing files in a directory by appending to string

I am using a batch file and need to be able to list all JavaScript files found at a relative path to where the batch script is run. The final list needs to be formatted as:
"C:\path\to\file1.js" "C:\path\to\file2.js" "C:\path\to\file3.js" etc..
So far I have done:
SET files=""
FOR /f "delims=" %%i IN ('dir /b /s ".\path\to\files\*.js"') DO (
SET files=!files! "%%i"
)
ECHO Files found: %files%
However, with the script above, all I get as output is:
Files found: "" C:\path\to\last\file.js
It only outputs the last file that was found in the directory. I don't know what the issue is here as to why it only appends the last file.
Run the Batch file below exactly as appears here:
#echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET "files="
FOR /f "delims=" %%i IN ('dir /b /s ".\path\to\files\*.js"') DO (
SET files=!files! "%%i"
)
ECHO Files found: %files%
If the output is not what you want, execute the next command directly from the command-line:
dir /b /s ".\path\to\files\*.js"
If previous line show the same files than the Batch file, then the problem is related to dir command.

Resources