?
Solved

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

Posted on 2012-09-12
14
Medium Priority
?
1,182 Views
Last Modified: 2012-09-13
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*

Open in new window

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. =]

Thanks in advance folks.
0
Comment
Question by:defecta
  • 7
  • 4
  • 3
14 Comments
 
LVL 85

Expert Comment

by:oBdA
ID: 38390466
You can do that by counting the lines:
@echo off
setlocal enabledelayedexpansion
set Line=2
set Folder=%userprofile%\AppData\Roaming\Adobe\Adobe Illustrator CS*
set /a i=0
for /f "delims=" %%a in ('dir /b /a:d "%Folder%"') do (
	set /a i+=1
	if "!i!"=="%Line%" echo %%a
)

Open in new window

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

Open in new window

0
 
LVL 59

Expert Comment

by:Bill Prew
ID: 38390521
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%

Open in new window

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

by:defecta
ID: 38390611
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

Open in new window


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
Veeam and MySQL: How to Perform Backup & Recovery

MySQL and the MariaDB variant are among the most used databases in Linux environments, and many critical applications support their data on them. Watch this recorded webinar to find out how Veeam Backup & Replication allows you to get consistent backups of MySQL databases.

 
LVL 85

Expert Comment

by:oBdA
ID: 38390972
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
set Folder=%userprofile%\AppData\Roaming\Adobe\Adobe Illustrator CS*
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"
	)
)

Open in new window

0
 
LVL 85

Accepted Solution

by:
oBdA earned 2000 total points
ID: 38392937
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
set CSFolder=%UserProfile%\AppData\Roaming\Adobe
set Mask=Adobe Illustrator CS*
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
)
:Menu
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 "%Index%"=="" goto Menu
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)
if %AllCleared%==0 goto Menu
:Done
echo Done.
goto :eof

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

set Cleared[%1]=X
goto :eof

Open in new window

0
 

Author Closing Comment

by:defecta
ID: 38393194
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 59

Expert Comment

by:Bill Prew
ID: 38393297
Props to oBdA, love it.

~bp
0
 

Author Comment

by:defecta
ID: 38393391
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

by:defecta
ID: 38393399
Yep, its official. I'm a noob. I was missing the quotes. lol.

Thanks again!
0
 
LVL 59

Expert Comment

by:Bill Prew
ID: 38393422
:-)
0
 

Author Comment

by:defecta
ID: 38393441
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 Add your clearing code here.
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

Open in new window

0
 
LVL 85

Expert Comment

by:oBdA
ID: 38394467
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 CSFolder=%userprofile%\AppData\Roaming\Adobe
set Mask=Adobe Illustrator CS*
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 CSMenu[!InstallCount!]=%%~nxa
	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 CSMenu[!InstallCount!]=%%~nxa
		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
)
:Menu
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 %%i%TAB%!Cleared[%%i]!%TAB%!CSArch[%%i]!%TAB%!CSMenu[%%i]!
)
echo ----------------------------------------------------------------------
echo Please choose the installation index to clean, or X to exit:
set Index=
set /p Index=^>
if "%Index%"=="" goto Menu
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)
if %AllCleared%==0 goto Menu
:Done
echo Done.
goto :eof
REM ======================================================================
:ClearFolder
set ClearName=!CSMenu[%1]!
set ClearFolder=!CSDir[%1]!
set ClearArch=!CSArch[%1]!
echo Clearing %ClearArch% installation of '%ClearName%' ...
echo Full path: '%ClearFolder%'
REM Add your clearing code here.
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

Open in new window

0
 

Author Comment

by:defecta
ID: 38397049
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

by:defecta
ID: 38397340
Can I just say again what an amazing piece of work oBda? Thanks again.
0

Featured Post

NFR key for Veeam Agent for Linux

Veeam is happy to provide a free NFR license for one year.  It allows for the non‑production use and valid for five workstations and two servers. Veeam Agent for Linux is a simple backup tool for your Linux installations, both on‑premises and in the public cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this post we will learn different types of Android Layout and some basics of an Android App.
Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question