Solved

# Batch command to return string from line 'X' in a file or preferably piped input

Posted on 2012-09-12
1,173 Views
Hi guys,

I am writing a little batch file for clearing the preferences (deleting the contents of a settings folder) from Adobe Illustrator when things go south and it starts to flake out (which happens frequently enough to necessitate this batch file unfortunately).

We have a have a few different versions of CS in use so the name of the folder changes with the version. I am writing this batch file so that its intelligent enough to find the folder without me having to program the different versions into the batch file. Also in the instance where it finds more than 1 version installed, it asks the user which version it wants to clear the preferences from.

Where I am stuck is trying to find a batch command that will allow me to echo 'X' line from some piped input like a
dir /b /ad %userprofile%\AppData\Roaming\Adobe\Adobe Illustrator CS*

and only return the line I choose.

Is this possible without any other dependencies or software required?

I have looked at FIND and FINDSTR and I cant see that either can be used for this purpose. But that doesn't mean I'm right about that. =]

0
Question by:defecta

LVL 82

Expert Comment

You can do that by counting the lines:
@echo off
setlocal enabledelayedexpansion
set Line=2
set /a i=0
for /f "delims=" %%a in ('dir /b /a:d "%Folder%"') do (
set /a i+=1
if "!i!"=="%Line%" echo %%a
)

Or you can use find's "/n" and find non-empty lines, then look for the line number:
@echo off
setlocal
set Line=2
for /f "tokens=1* delims=[]" %%a in ('dir /b /a:d "%Folder%" ^| find /v /n ""') do (
if "%%a"=="%Line%" echo %%b
)

0

LVL 51

Expert Comment

Here's another approach that will work well, utilizing builtin FIND and FINDSTR commands:

@echo off
set BaseDir=d:\ee\ee*
set Line=5
for /F "tokens=1* delims=]" %%A in ('dir /b /ad "%BaseDir%"^|find /v /n ""^|findstr /r /b /c:$%Line%$') do set DirName=%%B
echo %DirName%

The basic idea is run the DIR to get the list of folders, then pipe that into the FIND to add line numbers to the left of each line, then pipe that into FINDSTR to find the line number we want (line numbers are at the left of the line in []), and then use the outer FOR /F to separate the original line stuff from the line number to assign it to a variable.

~bp
0

Author Comment

Thanks for the quick reply guys.

I have been doing this to count the number of lines before going through the routine that prompts for clearing multiple folders.

For /f "tokens=* %%a IN ('dir /b %userprofile%\Appdata\Roaming\Adobe\Adobe Illustrator CS*^| Find  /c /v ""') DO IF %%a GTR 1 @echo There are multiple installations of CS


I then planned to read back each line from the 'dir' command, prompt the user to clear the folder with Y or N, increment the line count by +1, read the next line and prompt etc, until the line count equals %%a and then quit.

To use the code you guys have suggested I would need to substitute the value for %Line% with a variable also woudn't I?
0

LVL 82

Expert Comment

You don't need to count lines for that, as you're already processing the folder subfolder by subfolder. Try something like this:
@echo off
setlocal enabledelayedexpansion
for /f "delims=" %%a in ('dir /b /a:d "%Folder%"') do (
echo Processing %%~fa ...
set Clear=
set /p Clear=Do you want to clear this installation folder? [y^|N]
if /i "!Clear!"=="Y" (
echo Clearing %%a ...
REM Clear the settings folder in this line;
REM The current folder name will be in "%%a", the full folder name in ""%Folder%\%%a"
)
)

0

LVL 82

Accepted Solution

Just for fun, here's a script that will immediately clean a single installation/settings folder, and present a menu if more than one is found. The menu will loop until it's either left, or all installations have been cleared.
Just add your "clearing" code to the subroutine "ClearFolder" where indicated, starting in line 54.
@echo off
setlocal enabledelayedexpansion
REM In the following line, make sure there is a single tab character after "set TAB="
set TAB=
set /a InstallCount = 0
for /d %%a in ("%CSFolder%\%Mask%") do (
set /a InstallCount += 1
set CS[!InstallCount!]=%%~nxa
set Cleared[!InstallCount!]=-
)
if %InstallCount% EQU 0 (
echo No CS installation settings found.
goto Done
)
if %InstallCount% EQU 1 (
call :ClearFolder 1
goto Done
)
echo.
echo %InstallCount% CS installation settings have been found.
echo ----------------------------------------------------------------------
echo #%TAB%Clear%TAB%Folder
echo ----------------------------------------------------------------------
for /l %%i in (1, 1, %InstallCount%) do (
echo %%i%TAB%!Cleared[%%i]!%TAB%!CS[%%i]!
)
echo ----------------------------------------------------------------------
echo Please choose the installation index to clean, or X to exit:
set Index=
set /p Index=^>
if /i "%Index%"=="X" goto Done
if %Index% LSS 1 goto Menu
if %Index% GTR %InstallCount% goto Menu
call :ClearFolder %Index%
set AllCleared=1
for /l %%i in (1, 1, %InstallCount%) do (if "!Cleared[%%i]!"=="-" set AllCleared=0)
:Done
echo Done.
goto :eof

:ClearFolder
set ClearFolder=!CS[%1]!
echo Clearing '%ClearFolder%' ...
REM The settings folder name will be in %ClearFolder%;
REM to access the full path, use "%CSFolder%\%ClearFolder%"

set Cleared[%1]=X
goto :eof

0

Author Closing Comment

Damn dude, thank you so much! That does exactly what I need with way more flair than what I could do at this point in time!<br /><br />I'm reading over your code it mostly makes sense to me. If I can ask for the benefit of my learning, on line 10 near the end of the line there are some characters that I don't understand or haven't seen before. Its the "~nx" in "%%~nxa". What does that do?
0

LVL 51

Expert Comment

Props to oBdA, love it.

~bp
0

Author Comment

OK it should already be pretty clear that I am a noob at this but deleting the files from a folder should be a cinch but I am getting
The system cannot find the path specified.

when using the %CSFolder%\%ClearFolder%\en_GB for the path.

I have tested this on a test folder C:\test (works fine) which made me think I must have a permissions issue but running the batch as 'Administrator' didn't help.

I also tried 'run as' with a domain admin account and the batch wont even run at all. The batch window closes as quickly as it opens.

Something I don't understand is preventing me from finding/deleting the files and folders from this path. (I have no AV installed currently, so that cant be to blame either.)

EDIT: Never mind. I think I know what I was doing wrong. I am forgetting the " " around the path.
0

Author Comment

Yep, its official. I'm a noob. I was missing the quotes. lol.

Thanks again!
0

LVL 51

Expert Comment

:-)
0

Author Comment

found a new problem though.

I'm trying to duplicate your code again in the ClearFolder section and its not working the way I want.

Entering 'Y' the first time doesn't work but all subsequent attempts work fine. I thought I needed to set or clear the Clear64 variable but that doesn't seem to help.

Your infinite wisdom would be much appreciated. Here is the code I am working with.
:ClearFolder
set ClearFolder=!CS[%1]!
REM echo Clearing '%ClearFolder%' ...
REM The settings folder name will be in %ClearFolder%;
REM to access the full path, use "%CSFolder%\%ClearFolder%"

set CSdir=%CSFolder%\%ClearFolder%
for /f "tokens=*" %%b IN ('dir /b /ad "%CSDir%" ^| find "en_"') do set Lang=%%b
echo Clearing settings from folder "%ClearFolder%"
if EXIST "%CSDir%\%Lang%\x64\" (
echo ----------------------------------------------------------------------
echo %TAB%There is also a 64 bit version of Illustrator installed.
echo %TAB%If you are using the 64 bit version and you want to clear
echo %TAB%these settings press Y then Enter.
echo %TAB%Press X then Enter to exit.
echo ----------------------------------------------------------------------
set Clear64=
set /p Clear64=^>
if "%Clear64%"=="" goto ClearFolder
if /i "%Clear64%"=="X" goto Done
if /i "%Clear64%" NEQ "Y" goto ClearFolder
echo Yay, you chose to delete.
)
pause

0

LVL 82

Expert Comment

This should support the x64 installations as well; these will be treated the same as the x86 installations, as far as the menu is concerned.
Important change: the variable %ClearFolder% in the "ClearFolder" subroutine now contains the full/absolute path; for 32bit, this will be the same as the former "%CSFolder%\%ClearFolder%", for 64bit it will go all the way down to the %lang%\x64 folder.
The "%%~nxa" will expand to the name and extension of the file/folder in the variable %%a; enter "help call" for details.
@echo off
setlocal enabledelayedexpansion
set TAB=
set ContainsX64=0
set /a InstallCount = 0
echo Scanning for CS installation settings ...
for /d %%a in ("%CSFolder%\%Mask%") do (
set /a InstallCount += 1
set CSDir[!InstallCount!]=%%a
set CSArch[!InstallCount!]=32bit
set Cleared[!InstallCount!]=-
set Lang=\$
for /f "tokens=*" %%b in ('dir /b /ad "%%a" ^| find "en_"') do set Lang=%%b
if exist "%%a\!Lang!\x64" (
set ContainsX64=1
set /a InstallCount += 1
set CSDir[!InstallCount!]=%%a\!Lang!\x64
set CSArch[!InstallCount!]=64bit
set Cleared[!InstallCount!]=-
)
)
if %InstallCount% EQU 0 (
echo No CS installation settings found.
goto Done
)
if %InstallCount% EQU 1 (
call :ClearFolder 1
goto Done
)
echo.
echo %InstallCount% CS installation settings have been found.
if "%ContainsX64%"=="1" (
echo These include at least one x64 installation;
echo please pay attention to the architecture you want to clear.
)
echo ----------------------------------------------------------------------
echo Index%TAB%Clear%TAB%Arch.%TAB%Folder
echo ----------------------------------------------------------------------
for /l %%i in (1, 1, %InstallCount%) do (
)
echo ----------------------------------------------------------------------
echo Please choose the installation index to clean, or X to exit:
set Index=
set /p Index=^>
if /i "%Index%"=="X" goto Done
if %Index% LSS 1 goto Menu
if %Index% GTR %InstallCount% goto Menu
call :ClearFolder %Index%
set AllCleared=1
for /l %%i in (1, 1, %InstallCount%) do (if "!Cleared[%%i]!"=="-" set AllCleared=0)
:Done
echo Done.
goto :eof
REM ======================================================================
:ClearFolder
set ClearFolder=!CSDir[%1]!
set ClearArch=!CSArch[%1]!
echo Clearing %ClearArch% installation of '%ClearName%' ...
echo Full path: '%ClearFolder%'
REM The absolute settings folder path will be in %ClearFolder%;
REM If you need to check the installation architecture, use %ClearArch%, which will be either '32bit' or '64bit'.

set Cleared[%1]=X
goto :eof

0

Author Comment

Thanks so much again oBda.

It's funny because I was thinking about this problem this morning before I woke up and thought about solving it exactly how you just did. =)
0

Author Comment

Can I just say again what an amazing piece of work oBda? Thanks again.
0

## Featured Post

### Suggested Solutions

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Since upgrading to Office 2013 or higher installing the Smart Indenter addin will fail. This article will explain how to install it so it will work regardless of the Office version installed.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…