Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Batch Scripting Question - Search and Replace a Variable in a Variable?

I have a problem. I have a batch file which imitates the UNIX cd command. It takes a UNIX-style path inputted by the user, saves it as a var called upath2, converts it to a Windows-style path, and cd's to that directory (e.g. "/program files/7-zip" will become "C:\Program Files\7-Zip"). The Windows-like output will be saved as a var named upath2 and cmd's cd command will execute and change to that directory.

Along with this "UNIX" cd command, I have also created a batch file called "bashemu.bat", which gives me a bash-like prompt. All of the commands are doskey entries, which link to the bin and usr\bin folders that I created, which hold all of the .bat commands. It then executes "cmd /v /k" at the end so that I will be able to enter the doskey aliases and launch all of my UNIX-style commands.

Now, here's my problem: when I am cd-ing to a subdirectory of my C:\Users\xplinux557 folder (stored in an environment variable called "unixhome"), the prompt of bashemu changes from:

xplinux557@bash-pc:~$

to, for example:

xplinux557@bash-pc:/Users/xplinux557/Documents/MacSearch_v.1.4.3[1]/Skins/Blue/Icons$

Paths like these are too long to be used comfortably within bashemu in the Command Prompt, so I am trying to get the cd command to read the full upath2 variable and check to see if it contains the home path (as defined by unixhome) and simply replace that with a ~. This should turn this:

xplinux557@bash-pc:/Users/xplinux557/Documents/MacSearch_v.1.4.3[1]/Skins/Blue/Icons$

into this:

xplinux557@bash-pc:~/Documents/MacSearch_v.1.4.3[1]/Skins/Blue/Icons$

Aaaah, much better! My first approach was to convert upath's UNIX-style path to a Windows-Style path and name the new var upath2, and replace the text %unixhome% with a "~". This was how that code looked like:

:: set the batch file to retrieve all text from its parameters and replace all
:: unix-style slashes the user put in and replace those with a windows-style backslash
@echo off
set upath=%*
set upath=%upath:/=\%

:: cd to the directory that the user typed in, windows-style
cd "%upath%"

:: Set the upath2 var to the current directory and replace whatever unixhome was
:: a "~"
set upath2=%cd:%unixhome%="~"%

:: Remove the "C:" or "D:" from the quote
set upath2=%upath2:~2%

:: then, set the prompt to read:
:: "xplinux557@bash-pc:~/Documents/MacSearch_v.1.4.3[1]/Skins/Blue/Icons$"
prompt=%USERNAME%@%USERDOMAIN%:%upath2% $$ 

::EOF

Everything works perfectly fine, except for the line that reads:

set upath2=%cd:%unixhome%="~"%

I realize that it messes up and recognizes %cd:% and %="~"% as variables and gives me an error message. I'm truly very sorry for rambling on and on like this :), but long story short, is there a way to take the text of variable A, and replace that text if found in variable B?

Thank you all in advance!

like image 310
Eyal Kalderon Avatar asked Nov 15 '22 12:11

Eyal Kalderon


1 Answers

You can do an "eval" using CALL SET:

:: This does not work:  set upath2=%cd:%unixhome%=~%

:: This works: 
:::: uhome is the homepath, with unix-style (forward) slashes 
set uhome=%HOMEPATH:\=/%
:::: ucwd is the current working directory, with unix-style (forward) slashes 
set ucwd=%cd:\=/%

:: replace any occurence of uhome in ucwd with ~
CALL SET ucwd=%%ucwd:%uhome%=~%%

:: strip drive letter and colon
set ucwd=%ucwd:~2%

:: set prompt
prompt=%USERNAME%@%USERDOMAIN%:%ucwd% $$

When I call this I get User@Machine:~/Documents/dev/batch

ps: I think you had a bug. You don't want %cd:... . You want a variable with forward slashes.

also: this isn't going to be rock-solid reliable. Consider the case where you have a dir structure like this:

  c:\Users\John\Other
  c:\Users\John\Other\Users
  c:\Users\John\Other\Users\John 
  c:\Users\John\Other\Users\John\data 

... in this case you will get 2 twiddles.

like image 100
Cheeso Avatar answered Dec 01 '22 00:12

Cheeso