Echoing variables with colouring problem for filenames or directories

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
stevehero
Posts: 5
Joined: 27 Jan 2020 09:11

Echoing variables with colouring problem for filenames or directories

#1 Post by stevehero » 01 Apr 2020 15:16

I've taken this code from StackOverflow written by Jeb: https://stackoverflow.com/a/5344911/8262102

It works great for simple text but I cannot get it to work for echoing filenames or directory variables in the code below.

The error I'm getting is FINDSTR: Cannot open Directory...

The report fileList variable contains the content.

Code: Select all

"Z:\Music\Artist 1\01 Song.flac"
"Z:\Music\Artist 1\02 Song.flac"
"Z:\Music\Artist 2\01 Song.flac"
"Z:\Music\Artist 2\02 Song.flac"
"Z:\Music\Artist 2\03 Song.flac"
"Z:\Music\Artist 3\01 Song.flac"
"Z:\Music\Artist 3\02 Song.flac"
Here's the code in full, line 105 is where I'm having problems getting the !dirBase! variable working with colour.

Code: Select all

@echo off & title Example to go through a list of file and echo, Directory then file(s)... & color 02 & chcp 65001 >NUL
setlocal EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  set "DEL=%%a"
)
rem Prepare a file "X" with only one dot
<nul > X set /p ".=."

rem The following line creates a [DEL] [ASCII 8] [Backspace] character to use later
rem All this to remove [:]
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")

rem Set to overwrite the previous line in the buffer.
echo 1B 5B>ESC.hex & del ESC.bin >NUL 2>&1 & certutil -decodehex ESC.hex ESC.bin >NUL 2>&1 & set /P ESC=<ESC.bin
set "clearLine=%ESC%1F%ESC%0J"

goto :COMMON_VARIABLES

rem Variables
:COMMON_VARIABLES
call :CMD_SIZE 255 60 9999 TRUE
set "Ans_ScanRecursively_Switch=/s"
set "countFiles=0"
set "countFolderDirRoot=0"
set "countFolderDirSubs=0"
set "countTypeACC=0"
set "countTypeAIFF=0"
set "countTypeFLAC=0"
set "countTypeMP3=0"
set "fileBaseList=%Temp%\music-checker-base-list.tmp"
set "fileList=%Temp%\music-checker-list.tmp"
set "fileTypesAll=.flac .mp3 .aiff .acc"

goto :STEP1_GENERATE_FILE_LIST

:CMD_SIZE
chcp 850 >NUL & set "uiWidth=%1" & set "uiHeight=%2"
mode %uiWidth%,%uiHeight%
if %4==TRUE (set /a "uiHeightBuffer=uiHeight+%3")
if %4==TRUE (powershell.exe -ExecutionPolicy Bypass -Command ^
  "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%uiWidth%;$B.height=%uiHeightBuffer%;$W.buffersize=$B}")
if %4==FALSE (powershell.exe -ExecutionPolicy Bypass -Command ^
  "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%uiWidth%;$B.height=%uiHeight%;$W.buffersize=$B}")
chcp 65001 >NUL & goto :EOF

:STEP1_GENERATE_FILE_LIST
echo/> %fileList%
echo Please wait... Scanning folder(s) and file(s).
for /f "usebackq tokens=*" %%D in (%fileBaseList%) do (
  echo "%%~xD" | findstr "%fileTypesAll%" >NUL 2>NUL && (
    echo "%%~aD" | findstr /v "d" >NUL 2>NUL && (
      if exist "%%~fD" echo "%%~fD">> %fileList%
      rem This will count the file and file types.
      set /a countFiles+=1
      echo "%%~xD" | findstr ".flac" >NUL 2>NUL && ( set /a countTypeFLAC+=1 )
      echo "%%~xD" | findstr ".aiff" >NUL 2>NUL && ( set /a countTypeAIFF+=1 )
      echo "%%~xD" | findstr ".mp3"  >NUL 2>NUL && ( set /a countTypeMP3+=1 )
      echo "%%~xD" | findstr ".acc"  >NUL 2>NUL && ( set /a countTypeACC+=1 )
      )
    )
  echo "%%~aD" | findstr "d" >NUL 2>NUL && (
    rem echo ROOT FOLDER - "%%~D"
    set /a countFolderDirRoot+=1
    for /f "delims=" %%F in ('dir "%%~D" /b %Ans_ScanRecursively_Switch%') do (
      echo "%%~xF" | findstr "%fileTypesAll%" >NUL 2>NUL && (
        echo "%%~aF" | findstr /v "d" >NUL 2>NUL && (
          if exist "%%~fF" echo "%%~fF">> %fileList%
          rem This will count the file and file types.
          set /a countFiles+=1
          echo "%%~xF" | findstr ".flac" >NUL 2>NUL && ( set /a countTypeFLAC+=1 )
          echo "%%~xF" | findstr ".aiff" >NUL 2>NUL && ( set /a countTypeAIFF+=1 )
          echo "%%~xF" | findstr ".mp3"  >NUL 2>NUL && ( set /a countTypeMP3+=1 )
          echo "%%~xF" | findstr ".acc"  >NUL 2>NUL && ( set /a countTypeACC+=1 )
          rem This will count the sub directories
          set "dirBase=%%~dpF" && setlocal EnableDelayedExpansion
          if /i not "!dirNext!"=="!dirBase!" (echo "!dirBase!" | find "d" >NUL 2>NUL && (
            endlocal && set /a countFolderDirSubs+=1 && setlocal EnableDelayedExpansion
            )
          )
          endlocal && set "dirNext=%%~dpF"
          )
        )
      )
    )
  )
goto :STEP_2_REPORT_SCANNED

:STEP_2_REPORT_SCANNED
echo %clearLine%Scanned            Found
call :COLOR_TXT 07 "Root folder(s)     %countFolderDirRoot%"        & echo/
call :COLOR_TXT 07 "Sub folder(s)      %countFolderDirSubs%"   & echo/
echo/
call :COLOR_TXT 07 "FLAC file(s)       %countTypeFLAC%"       & echo/
call :COLOR_TXT 07 "AIFF file(s)       %countTypeAIFF%"       & echo/
call :COLOR_TXT 07 "MP3 file(s)        %countTypeMP3%"        & echo/
call :COLOR_TXT 07 "ACC file(s)        %countTypeACC%"        & echo/
call :COLOR_TXT 07 "Total file(s)      %countFiles%"          & echo/
echo/
goto :STEP_3_PROCESS_TEXTFILE

:STEP_3_PROCESS_TEXTFILE
for /f "usebackdelims=" %%D in ("%fileList%") do (
  set "dirBase=%%~dpD" && setlocal EnableDelayedExpansion
  if /i not "!dirNext!"=="!dirBase!" (echo "!dirBase!" | find "d" >NUL 2>NUL && (
    rem call :COLOR_TXT 07 "Directory   [ !dirBase! ]" & echo/
    echo Directory   [ !dirBase! ]
    )
  )
  endlocal && set "dirNext=%%~dpD"
  set "filename=%%~fD"
  call :STEP_4_PROCESS_FILES
  )
goto :EOF

:STEP_4_PROCESS_FILES
echo               { "%filename%" }
goto :EOF

:COLOR_TXT
set "param=^%~2" !
set "param=!param:"=\"!"
findstr /p /A:%1 "." "!param!\..\X" nul
<nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
exit /b

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Echoing variables with colouring problem for filenames or directories

#2 Post by jeb » 02 Apr 2020 02:41

Hi stevehero,

most of my code is more or less only a proof of concept :!:
The color sample, too.
Long time ago, I developed it to show that it's even possible to colorize characters.

But to use it as a function, you better switch to the code of Dave SO: How to have multiple colors in a Windows batch file?

Or search for the function of Carlos, that is also an advanced version of the same idea.

Your current problem is a direct result of my proof of concept, it doesn't handle the backslash nor parameters starting with a drive.
It's easy to solve, but for that better use any of the other solutions

jeb

stevehero
Posts: 5
Joined: 27 Jan 2020 09:11

Re: Echoing variables with colouring problem for filenames or directories

#3 Post by stevehero » 02 Apr 2020 05:55

Thank you. I've tried that and it works. Although with the character limit I'll probably end up not bothering with it and just stick with plain old colours.

I quite like the PowerShell way too. I've modified the code on that same thread of skrebbels' code. https://stackoverflow.com/a/12894047/8262102
Although special characters are not supported with that.

Code: Select all

@echo off
rem Based on: https://stackoverflow.com/a/12894047/8262102

call :TEXTCLR "Blue" "Yellow"    "Something Something"
call :TEXTCLR "Yellow" "Magenta" "Done!"
goto :eof

:TEXTCLR
powershell -Command Write-Host "%~3" -foreground "%~1" -background "%~2"
goto :eof

rem https://docs.microsoft.com/en-us/dotnet/api/system.consolecolor?view=netframework-4.8
rem Colours available
rem Black
rem Blue
rem Cyan
rem DarkBlue
rem DarkCyan
rem DarkGray
rem DarkGreen
rem DarkMagenta
rem DarkRed
rem DarkYellow
rem Gray
rem Green
rem Magenta
rem Red
rem White
rem Yellow
Here's my updated code at the bottom to include the new colorprint fn.

And the .txt file that I have:

Code: Select all

"Z:\Downloads\Downloads\Artist 1\01 Song.flac"
"Z:\Downloads\Downloads\Artist 1\02 Song.flac"
"Z:\Downloads\Downloads\Artist 1\03 Song.flac"
"Z:\Downloads\Downloads\This is a really really long pathname for some unknown reason\Really its silly how long it is\This is a song made for dancing 01.flac"
"Z:\Downloads\Downloads\This is a really really long pathname for some unknown reason\Really its silly how long it is\This is a song made for dancing 02.flac"
It throws an error:

Code: Select all

FINDSTR: Cannot open Directory       [ Z:\Downloads\Downloads\This is a really really long pathname for some unknown reason\Really its silly how long it is\ ]\..\x

Code: Select all

@echo off & title Example to go through a list of file and echo, Directory then file(s)... & color 02 & chcp 65001 >NUL
setlocal

rem Set to overwrite the previous line in the buffer.
echo 1B 5B>ESC.hex & del ESC.bin >NUL 2>&1 & certutil -decodehex ESC.hex ESC.bin >NUL 2>&1 & set /P ESC=<ESC.bin
set "clearLine=%ESC%1F%ESC%0J"

call :INITCOLORPRINT

goto :COMMON_VARIABLES

rem Variables
:COMMON_VARIABLES
call :CMD_SIZE 275 80 9999 TRUE
set "countFiles=0"
set "countFolderDirRoot=0"
set "countFolderDirSubs=0"
set "countTypeACC=0"
set "countTypeAIFF=0"
set "countTypeFLAC=0"
set "countTypeMP3=0"
set "fileList=%Temp%\music-checker-list.tmp"
set "fileListBase=%Temp%\music-checker-base-list.tmp"
set "fileTypesAll=.flac .mp3 .aiff .acc"
set "scanRecursively_Switch_Ans=/s"

rem goto :STEP_1_GENERATE_FILE_LIST
goto :STEP_2_START_MAIN_ROUTINE

:CMD_SIZE
chcp 850 >NUL & set "uiWidth=%1" & set "uiHeight=%2"
mode %uiWidth%,%uiHeight%
if %4==TRUE (set /a "uiHeightBuffer=uiHeight+%3")
if %4==TRUE (powershell.exe -ExecutionPolicy Bypass -Command ^
  "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%uiWidth%;$B.height=%uiHeightBuffer%;$W.buffersize=$B}")
if %4==FALSE (powershell.exe -ExecutionPolicy Bypass -Command ^
  "&{$H=get-host;$W=$H.ui.rawui;$B=$W.buffersize;$B.width=%uiWidth%;$B.height=%uiHeight%;$W.buffersize=$B}")
chcp 65001 >NUL & goto :EOF

:STEP_1_GENERATE_FILE_LIST
echo/> %fileList%
echo Please wait... scanning folder(s) and file(s).
for /f "usebackq tokens=*" %%D in (%fileListBase%) do (
  echo "%%~xD" | findstr "%fileTypesAll%" >NUL 2>NUL && (
    echo "%%~aD" | findstr /v "d" >NUL 2>NUL && (
      if exist "%%~fD" echo "%%~fD">> %fileList%
      rem This will count the file and file types.
      set /a countFiles+=1
      echo "%%~xD" | findstr ".flac" >NUL 2>NUL && ( set /a countTypeFLAC+=1 )
      echo "%%~xD" | findstr ".aiff" >NUL 2>NUL && ( set /a countTypeAIFF+=1 )
      echo "%%~xD" | findstr ".mp3"  >NUL 2>NUL && ( set /a countTypeMP3+=1 )
      echo "%%~xD" | findstr ".acc"  >NUL 2>NUL && ( set /a countTypeACC+=1 )
      )
    )
  echo "%%~aD" | findstr "d" >NUL 2>NUL && (
    rem echo ROOT FOLDER - "%%~D"
    set /a countFolderDirRoot+=1
    for /f "delims=" %%F in ('dir "%%~D" /b %scanRecursively_Switch_Ans%') do (
      echo "%%~xF" | findstr "%fileTypesAll%" >NUL 2>NUL && (
        echo "%%~aF" | findstr /v "d" >NUL 2>NUL && (
          if exist "%%~fF" echo "%%~fF">> %fileList%
          rem This will count the file and file types.
          set /a countFiles+=1
          echo "%%~xF" | findstr ".flac" >NUL 2>NUL && ( set /a countTypeFLAC+=1 )
          echo "%%~xF" | findstr ".aiff" >NUL 2>NUL && ( set /a countTypeAIFF+=1 )
          echo "%%~xF" | findstr ".mp3"  >NUL 2>NUL && ( set /a countTypeMP3+=1 )
          echo "%%~xF" | findstr ".acc"  >NUL 2>NUL && ( set /a countTypeACC+=1 )
          rem This will count the sub directories
          set "dirBase=%%~dpF" && setlocal EnableDelayedExpansion
          if /i not "!dirNext!"=="!dirBase!" (echo "!dirBase!" | find "d" >NUL 2>NUL && (
            endlocal && set /a countFolderDirSubs+=1 && setlocal EnableDelayedExpansion
            )
          )
          endlocal && set "dirNext=%%~dpF"
          )
        )
      )
    )
  )
goto :STEP_2_START_MAIN_ROUTINE

:STEP_2_START_MAIN_ROUTINE
echo %clearLine%Scanned         Found
call :COLORPRINT 07 "Root folders    %countFolderDirRoot%" /n
call :COLORPRINT 07 "Root folders    %countFolderDirRoot%" /n
call :COLORPRINT 07 "Sub folders     %countFolderDirSubs%" /n
echo/
call :COLORPRINT 07 "FLAC files      %countTypeFLAC%"      /n
call :COLORPRINT 07 "AIFF files      %countTypeAIFF%"      /n
call :COLORPRINT 07 "MP3 files       %countTypeMP3%"       /n
call :COLORPRINT 07 "ACC files       %countTypeACC%"       /n
call :COLORPRINT 07 "Total files     %countFiles%"         /n
echo/
goto :STEP_3_PROCESS_TEXTFILE

:STEP_3_PROCESS_TEXTFILE
for /f "usebackdelims=" %%D in ("%fileList%") do (
  set "dirBase=%%~dpD" && setlocal EnableDelayedExpansion
  if /i not "!dirNext!"=="!dirBase!" (echo "!dirBase!" | find "d" >NUL 2>NUL && (
    call :COLORPRINT 07 "Directory       [ !dirBase! ]" /n
    rem echo "Directory       [ !dirBase! ]"
    )
  )
  endlocal && set "dirNext=%%~dpD"
  echo                 { "%%~fD" }
  )
call :CLEANUPCOLORPRINT
exit /b

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

:COLORPRINT Color  Str  [/n]
setlocal
set "str=%~2"
call :COLORPRINTVAR %1 str %3
exit /b

:COLORPRINTVAR  Color  StrVar  [/n]
if not defined %~2 exit /b
setlocal enableDelayedExpansion
set "str=a%DEL%!%~2:\=a%DEL%\..\%DEL%%DEL%%DEL%!"
set "str=!str:/=a%DEL%/..\%DEL%%DEL%%DEL%!"
set "str=!str:"=\"!"
pushd "%temp%"
findstr /p /A:%1 "." "!str!\..\x" nul
if /i "%~3"=="/n" echo(
exit /b

:INITCOLORPRINT
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do set "DEL=%%a"
<nul >"%temp%\x" set /p "=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%.%DEL%"
exit /b

:CLEANUPCOLORPRINT
del "%temp%\x"
exit /b

Post Reply