user6250760
user6250760

Reputation:

Batch file - Dir's result separated

I ran into a problem while trying to finish up my own file explorer. This is the files in my working directory. I would like it to return:

FolderFoo     FileFoo
FolderBar     FileBar

However my script returns:

FolderFoo FolderBar FileFoo FileBar

Does anybody have some idea? Here's my script:

echo.|set /p some=>"%~Dp0foo\bar\FileExprTemp.tmp"

for /F "tokens=*" %%a in ('dir /B') do (
    echo.|set /p some="%%a ">>%~Dp0foo\bar\FileExprTemp.tmp
)

type %~dp0foo\bar\FileExprTemp.tmp

Upvotes: 2

Views: 615

Answers (5)

Stephan
Stephan

Reputation: 56190

As the question is formulated, this simple line should do:

dir /d|findstr /bvc:" "

dir /d does the table thing (even takes care of lenght of filenames), findstr /bvc:" " removes header and summary.

for folders only:

dir /d /ad|findstr /bvc:" "

for files only:

dir /d /a-d|findstr /bvc:" "

Upvotes: 0

A Cat Named Tiger
A Cat Named Tiger

Reputation: 403

I supposed that you have more than one file in your subfolders.

Code:

@echo off

set /p Parent=Type parent folder location ^> 

for /d %%D in ("%Parent%\*") do (
    <nul set /p =%%~nxD
    for /f "tokens=1-2 delims=:" %%F in ('dir /b "%%~fD" ^| findstr /n .') do (
        if "%%F"=="1" (echo(    %%G) else (echo(        %%G)
    )
    echo.
)

pause>nul

Using <nul set /p will allow you to print a string without adding new line after your string.

I think there are simpler methods, which I cannot think of.

Upvotes: 0

MC ND
MC ND

Reputation: 70933

Not even a refined process, but this shows how to handle the read of the two lists in parallel while provinding a "formated" output.

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Get root folder from command line - Default to current directory
    for %%a in ("%~f1.") do set "root=%%~fa"

    rem Prepare padding for directories column
    set "folderWidth=30"
    setlocal enabledelayedexpansion
    set "padding= "
    for /l %%a in (1 1 %folderWidth%) do set "padding=!padding! "
    endlocal & set "padding=%padding%"

    rem Prepate two files to store files and directories lists
    for %%d in ("%temp%\directories.%random%%random%%random%.tmp") do (
    for %%f in ("%temp%\files.%random%%random%%random%.tmp") do (

        rem Retrieve the list of directories and files into the temp files
        dir "%root%" /b /on /ad  > "%%~fd" 2>nul 
        dir "%root%" /b /on /a-d > "%%~ff" 2>nul 

        rem Assign each temporary file to a separate stream 
        rem and call the code to process them 
        9<"%%~fd" 8<"%%~ff" call :dumpPairs

        rem Clean up temporary files
    ) & del /q "%%~ff"
    ) & del /q "%%~fd"

    rem All done, leave
    goto :eof


    rem Read stream 9 to retrieve folder name - Clean var on failure
    rem Read stream 8 to retrieve file name - Clean var on failure
    rem If both variables are uninitialized, there is nothing more to do
    rem Concatenate folder name and padding 
    rem Echo the padded folder name and file name
    rem Repeat the process

:dumpPairs
    <&9 set /p "directory=" || set "directory="
    <&8 set /p "file="      || set "file="
    if not defined directory if not defined file goto :eof

    set "line=%directory%%padding%"
    setlocal enabledelayedexpansion
    echo(!line:~0,%folderWidth%! !file!
    endlocal

    goto :dumpPairs

Upvotes: 3

abelenky
abelenky

Reputation: 64692

This is my partial solution.

Like geisterfurz007 said, the trouble is with formatting. But this assembles files and directories side-by-side. Maybe it will help you make progress?

@echo off & goto :main

:WriteLine [%1|Skip]
    setlocal

    :: Apparently for /F "skip=0" is an error,
    :: So I have to check for skip=0, and avoid that.
    :: (To me, that is a bug, as skip=0 should be perfectly valid)
    if %1 GTR 0 set SKIP_CMD="skip=%1"
    for /F %SKIP_CMD% %%a in (Dirs.txt) do (set DIRNAME=%%a & goto :doFile)
    :doFile
    for /F %SKIP_CMD% %%a in (Files.txt) do (set FILENAME=%%a & goto :doOutput)
    :doOutput

    echo %DIRNAME% %FILENAME% >> FileExprTemp.tmp
exit /B



:main
    dir /B /AD  > Dirs.txt              &:: Get all the Directories into one file
    for /F "tokens=3" %%a in ('find /V /C "" Dirs.txt') do set DIR_COUNT=%%a

    dir /B /A-D > Files.txt             &:: Get all the files into a different file
    for /F "tokens=3" %%a in ('find /V /C "" files.txt') do set FILE_COUNT=%%a


    for /L %%a in (0,1,%FILE_COUNT%) do (call :WriteLine %%a)   &:: Append each Directory and Filename to Output

    type FileExprTemp.tmp               &:: Show the results
    del dirs.txt                        &:: Clean up temporary files 
    del files.txt
exit /B

Upvotes: 3

geisterfurz007
geisterfurz007

Reputation: 5874

After working around and testing and trying and golfing I got a (somewhat) working code:

@echo off
setlocal EnableDelayedExpansion
set counter=0
for /f "delims=" %%d in ('dir /ad /b') do (
set outputs[!counter!]=%%d
set /a counter=!counter!+1
)
set counter=0
for /f "delims=" %%f in ('dir /a-d /b') do (
call echo %%outputs[!counter!]%%            %%f >> FileExprTemp.tmp
set /a counter=!counter!+1
)
type FileExprTemp.tmp

Explanation:

Read the content of the command dir /ad /b that only has the directories as content (including . and ..) into the list outputs

Read the content of the command 'dir /a-d /b' which explicitly excludes directories and echo it together with the already existing list content into the temporary file.

type the content of the file.

Problem with above: Formatting. There is nothing to make it look like a table or anything. Except your folder names are all the same length... Then you are a well sorted person!

I hope this is enough of a template to work from and to make it fit your closer desires!

Upvotes: 3

Related Questions