Batch file Remove last charater on last loop item - batch-file

I have batch file that gives-me all files inside a folder and creates a txt file with the file names, separated by comma ",". On the last loop i need the comma don't appear.
Results: DOc1,DOc2,DOc2,DOc2,DOc1,
This is What i need:(Whithout last comma) DOc1,DOc2,DOc2,DOc2,DOc1
I think i'm missing something on my code.
#echo off
<nul (
for /f "eol=: delims=" %%F in ('dir /b /o:n ^| findstr /vile ".bat .txt"') do set /p ="%%F, "
) >fileList.txt
Thanks for any help

You could use a method of determining whether or not the file is the first returned, adjusting the output accordingly. In this case, the findstr command you're using already, has a method of determining the line number, (its /N option):
#Echo Off
SetLocal EnableExtensions
< NUL (
For /F "Tokens=1* Delims=:" %%G In (
'Dir /B /A:-D /O:N ^| %__AppDir__%findstr.exe /VNLIE ".bat .txt"'
) Do If %%G Equ 1 (Set /P "=%%H") Else Set /P "=, %%H"
) > "fileList.txt"

Define a flag-like variable that indicates whether it is the first iteration and apply the separator conditionally:
#echo off
set "FIRST=#"
< nul (
for /F "eol=: delims=" %%F in ('dir /B /O:N ^| findstr /VILE ".bat .txt"') do (
if not defined first (set /P =", ") else set "FIRST="
set /P ="%%F"
)
) > "fileList.txt"

Related

How to use multiple find commands in the for loop in batch?

I have the following code:
set "string_pdf=<module>PDF-hul</module>"
set string1=Well-Formed and valid
set /a loop100=0
for /f "tokens=*" %%i in ('dir /a-d /b /s %output%') do (
for /f "tokens=3 delims=>/<" %%p in ('find "%string_pdf%" "%%i" && find "%string1%" "%%i" ') do (
echo %%~ni >> %output%\pdf_hul.txt
set /a loop100+=1
)
)
I'm going through all XML's that are located in the %output% folder and trying to find the co-occurrence of Well-Formed and valid and <module>PDF-hul</module> in one xml file. This code works when I'm searching only with one find command for one variable. But when I add the second one I get a syntactical error.
How to find both variables string_pdf and string1 in one xml (aren't in one line)?
You would have to escape the && --> ^&^& but
IMO the 2nd for isn't neccessary simply use a findstr with two strings and
a conditional execution on success && and suppress any output of the findstr
:: Q:\Test\2018\11\01\SO_53102597.cmd
#Echo off
set output=X:\Path
set "string_pdf=<module>PDF-hul</module>"
set string1=Well-Formed and valid
set /a loop100=0
for /f "tokens=*" %%i in ('dir /a-d /b /s "%output%*.xml"') do (
findstr /IM /c:"%string_pdf%" "%%i" >NUL 2>&1 && (
findstr /IM /c:"%string1%" "%%i" >NUL 2>&1 && (
echo %%~ni >> %output%\pdf_hul.txt
set /a loop100+=1
)
)
)
set loop

Batch Script merging PDF's with pdftk

Thanks in advance for any help given.
After searching through all relative threads and google search I'm stumped on finding a solution to output a variable name for merging two PDF's.
So I have 100's of PDF's I need to combine (two at a time) in a folder c:/test
The files are set out like below
Company Name Invoice No 123456
Company Name Invoice No 123456 details
Now I have managed to move two files at a time to a different folder and merge them but can't seem to get the desrired output name I'm after which is to put a week ending date in front (or at the end, not fussed) of the first merged filename. Below is the code I have thus far which works but the output file name is blank but gets created.
Very new to batch scripting and would appreciate any help :)
#echo off
setlocal enableextensions enabledelayedexpansion
set pdftk=C:\Program Files (x86)\PDFtk Server\bin\pdftk.exe
set Source=C:\test
set Target=C:\test\test2
set num=2
set filenumber=1
for /F "tokens=1,2 delims=:" %%f in ('dir /b /a-d "%source%\*.pdf" ^| findstr /n "^" ') do (
if %%f leq %num% (
copy "%source%\%%g" "%target%" /y > nul
) else goto endCopy
)
:endCopy
endlocal
for /F "tokens=1,2 delims=:" %%f in ('dir /b /a-d "%target%\*.pdf" ^| findstr /n "^" ') do (
if %%f leq %filenumber% ( set file=%%~nA
)
)
pdftk *.pdf cat output we_19_9_2017_%file%.pdf
In endCopy you are trying to get the name of A whereas you are iterating with f. Use set file=%%~nf to set the name of file or set file=%%~ng for second file.
And move endlocal at the end to expand !file! at the end of script like this (note the !):
:endCopy
set "cmd=dir /b /a-d "%target%\*.pdf" ^| findstr /n "^""
for /F "tokens=1,2 delims=:" %%f in ('%cmd%') do if %%f leq %filenumber% set file=%%~nf
pdftk *.pdf cat output we_19_9_2017_!file!.pdf
endlocal
Read more about DelayedExpansion at: https://ss64.com/nt/delayedexpansion.html
The last command doesn't use the target folder for the input files and thus looks for the input files in the current folder, so either include the path or first change to the target path.
Also you set a path-variable for pdftk but don't use it.
If this path isn't included in the %path% it can't be find.
Try this (untested)
#echo off
setlocal enableextensions enabledelayedexpansion
set "pdftk=C:\Program Files (x86)\PDFtk Server\bin\pdftk.exe"
set "Source=C:\test"
set "Target=C:\test\test2"
set num=2
set filenumber=1
for /F "tokens=1,2 delims=:" %%f in (
'dir /b /a-d "%source%\*.pdf" ^| findstr /n "^" '
) do if %%f leq %num% (
copy "%source%\%%g" "%target%" /y > nul
) else goto endCopy
:endCopy
endlocal
for /F "tokens=1,2 delims=:" %%f in (
'dir /b /a-d "%target%\*.pdf" ^|findstr /n "^" '
) do if %%f leq %filenumber% set file=%%~nf
PushD "%Target%"
"%pdftk%" *.pdf cat output we_19_9_2017_%file%.pdf
PopD

How to remove full path name and add comma for the first two columns created?

I am struggling to edit the below command line to only give the name of the file name instead of the full path name and file. I would also want a comma straight after that and another comma straight after the second column (which is the created date done in do, as its a delimited notepad file.
#echo off
setlocal enabledelayedexpansion
set _SRCDIR=C:\Users\hyea\Desktop\Testing\Source
set _DSTDIR=C:\Users\hyea\Desktop\Testing\Target
for /f "delims=" %%f in ('dir /b /a-d "!_SRCDIR!\*.cos"') do (
type "!_SRCDIR!\header.txt" > "!_DSTDIR!\%%f"
call :handle_file "!_SRCDIR!\%%f" "!_DSTDIR!\%%f"
)
goto :eof
:handle_file
set _TMPVAR0=%~t1
setlocal disabledelayedexpansion
for /f "usebackq delims=" %%g in (`"findstr /n ^^ %1"`) do (
echo %%g
set "_TMPVAR1=%%g"
setlocal enabledelayedexpansion
set "_TMPVAR1=!_TMPVAR1:*:=!"
echo.%~1 !_TMPVAR0: =-! !_TMPVAR1!>> %2
endlocal
)
goto :eof
[untested, since you give no indication of the data involved and present a confused list of the outputs you need]
#echo off
setlocal enabledelayedexpansion
set _SRCDIR=C:\Users\hyea\Desktop\Testing\Source
set _DSTDIR=C:\Users\hyea\Desktop\Testing\Target
for /f "delims=" %%f in ('dir /b /a-d "!_SRCDIR!\*.cos"') do (
type "!_SRCDIR!\header.txt" > "!_DSTDIR!\%%f"
set "_TMPVAR0=%~tf"
set "_tmpvar0=!_tmpvar0: =-!"
for /f "tokens=1*delims=:" %%g in (`findstr /n ^^ ""`) do (
echo(%~nf,!_TMPVAR0!,%%h>> "!_DSTDIR!\%%f"
)
)
goto :eof
which should insert the header then copy each line, including blank lines, prefixing each line with
filenameonly,the filedate/time (with spaces replaced by -),linebody

How to "cd" into all folders step-by-step which are in an text file?

UPDATE
Here's my full code:
cd "C:\Users"
DIR /A:D /S /B > "%appdata%\folder_overview.txt"
type "%appdata%\folder_overview.txt" | findstr /v AppData | findstr /v All.Users | findstr /v Public >> "%appdata%\newfolder.txt"
move "%appdata%\newfolder.txt" "%appdata%\folder_overview.txt"
:repeatuntilfilesizezero
set LINES=0
for /f "delims==" %%I in (%appdata%\folder_overview.txt) do (
set /a LINES=LINES+1
)
set /a LINES=LINES-1
more +%LINES% < "%appdata%\folder_overview.txt" >> "%appdata%\last_folder.txt"
Setlocal EnableDelayedExpansion
set content=
for /f "delims=" %%i in (%appdata%\last_folder.txt) do set content=!content! %%i
pause
cd %content%
type "%appdata%\folder_overview.txt" | findstr /v "%content%" >> "%appdata%\newfolder.txt"
move "%appdata%\newfolder.txt" "%appdata%\folder_overview.txt"
DEL "%appdata%\last_folder.txt"
FOR %%S IN (%appdata%\folder_overview.txt) DO set size=%%~zS
echo %size%
IF %size% gtr 0 echo goto :repeatuntilfilesizezero
IF %size% equ 0 echo "null"
pause
I noticed that it's totally worth that the last line is a blank line.
I just want the following:
list all folders
"cd" to the last folder in "folder_overview.txt" and delete the last line from the file
check if "folder_overview.txt" is empty
-> if not empty, just goto label ":repeatuntilfilesizezero"
-> if empty, goto exit
So finally "cd" step-by-step in all folders which are in "folder_overview.txt".
Currently the "goto :repeatuntilfilesizezero" does not work. It do not jumps to the label.
Hannir
To retrieve the non-empty last line of a text file, you do not need to count the lines and skip all but one with more. Simply use a for /F loop with a variable assignment instead, so the variable holds the last line finally:
> "%APPDATA%\last_folder.txt" (
for /F usebackq^ delims^=^ eol^= %%L in ("%APPDATA%\folder_overview.txt") do (
set "LINE=%%L"
)
setlocal EnableDelayedExpansion
echo(!LINE!
endlocal
)
Delayed variable expansion is used here to avoid trouble with some special characters like ^, &, ( and ) in the last line.
In case the file does not contain duplicate lines, the following code could be used to remove the last line:
> "%APPDATA%\folder_overwiew.txt" findstr /L /X /V /G:"%APPDATA%\last_folder.txt" "%APPDATA%\folder_overwiew.txt"
In case the file might contain duplicates, the following snippet could be used instead:
set "LINE="
> "%APPDATA%\folder_overwiew.txt" (
for /F usebackq^ delims^=^ eol^= %%L in ("%APPDATA%\folder_overview.txt") do (
setlocal EnableDelayedExpansion
if defined LINE echo(!LINE!
endlocal
set "LINE=%%L"
)
)
I can't detect what you want to do, but as you cd into every directory, I assume you want to do something in every folder in the tree:
#echo off
cd /d "c:\users"
for /f %%i in (' dir /s /b /ad ^|findstr /v "AppData All.Users Public" ') do (
pushd "%%i"
echo now working in: %%i
echo doing something here in %%~ni
popd
)

Batch Script to Delete Files with Unique Root Stem in Directory

Is it possible to write a batch file that deletes all files in a directory for which the first n characters of the file's root name do not match the first n characters of any other filenames in that directory? For instance, suppose the directory contains the following:
Purcell_HenryA.txt
Purcell_HenryB.txt
Casaubon_IsaacA.txt
In this case, we would want to delete all files in the directory whose first 13 characters did not match the first 13 characters in any other files in the directory. (That is, we'd want to delete only Casaubon_IsaacA.txt.) I have tracked down scripts that delete all files with unique extensions in a directory, but don't know how to begin to write this script, and would therefore be grateful for any leads on the question.
This checks for root filenames of 14 characters and over - and if there is only 1 file with the same leading 13 characters then it will echo del. Remove the echo to make it perform the deletion.
#echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('dir /b /a-d') do (
set "part=%%~na"
if not "!part:~13,1!"=="" (
set "part=!part:~0,13!"
for /f "delims=" %%b in ('dir /b /a-d "!part!*.*" ^|find /c "!part!" ') do (
if %%b EQU 1 echo del "%%a"
)
)
)
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET target=u:\testdir
DIR /b /a-d %target%
echo====^^ names IN DIR ^^===
SET length=13
SET match=:
SET "candidate="
FOR /f "delims=" %%i IN ('dir /b/a-d "%target%\*"') DO (
SET filename=%%i
SET section=!filename:~0,%length%!
IF !section!==!match! (SET "candidate=") ELSE (
IF DEFINED candidate ECHO(DEL %target%\!candidate!
SET candidate=%%i
SET match=!section!
)
)
IF DEFINED candidate ECHO(DEL %target%\!candidate!
GOTO :EOF
Test result:
abc123_uniquename.txt
another_uniquename.txt
duplicate_name1234.txt
duplicate_name1235.txt
duplicate_name1236.txt
hello.txt
repeated__name1236.txt
repeated__name1235.txt
unique__name1235.txt
===^ names IN DIR ^===
DEL u:\testdir\abc123_uniquename.txt
DEL u:\testdir\another_uniquename.txt
DEL u:\testdir\hello.txt
DEL u:\testdir\unique__name1235.txt
If you are happy after testing, remove both ECHO( to activate the delete function.
For this code file name = name+extension:
#echo off &SETLOCAL enabledelayedexpansion
FOR %%a IN (*) DO (
SET "search=%%~a"
IF "!search:~13!" neq "" (
FOR /f "delims=[]" %%b IN ('dir /b /a-d /on "!search:~0,13!*" ^| find /n "!search:~0,13!"') DO SET found=%%b
IF !found! equ 1 ECHO DEL "%%~a"
)
)
And because I coose a very similar solution as foxidrive here is another one:
#echo off &SETLOCAL enabledelayedexpansion
FOR %%a IN (*) DO (
SET search=%%a
IF "!search:~13!" neq "" SET /a $!search:~0,13!+=1 2>nul
)
FOR /f "tokens=1*delims=$=" %%a IN ('set "$"') DO if %%b equ 1 echo del "%%~a*"
The way i'd go about this is as follows, i will explain the logic and i'll leave you to do the coding.
You will parse all the file names into variables, while increasing each time.
Then you will set a limit to the number of loops to go through. Then you will search the first 13 characters of the file name and if the number of lines is equal to 1 then delete it. After you will increase the variable by 1 and go through the loop, at the end of each loop it will check if it has reached the limit aka the number of files in the directory, if it has reached the limit, end the loop, otherwise continue.
hah, i finally decided to do it after a guy decided to use my idea i described into actual code, anyway this is way shorter and a lot faster than his, tested+verified to work:
#echo off & setlocal enabledelayedexpansion
set dir=directoryyouwanttosearchin
for /f "delims=" %%a in ('dir /A:a /b %dir%') do set /A name+=1 & set file!name!=%%a
:LOOP
set /A cnt+=1
for /f "delims=" %%a in ('dir /A:a /b %dir% ^| find /C /I "!file%cnt%:~0,13!"') do set lines=%%a
if %lines%==1 del %dir%\!file%cnt%! > nul
if %cnt% NEQ %name% Goto :LOOP
exit /b
That's 9 lines :).

Resources