views:

324

answers:

2

Hello all!

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!

A: 

Turn on delayed expansion with

setlocal enabledelayedexpansion

and use

set upath2=!cd:%userprofile%=~!

Note that setlocal will start a new variable scope and any changes to environment variables done inside that scope won't persist outside of it.

You can, however, do the following for a one-off use:

setlocal enabledelayedexpansion
set upath2=!cd:%userprofile%=~!
endlocal&set upath2=%upath2%
Joey
Thank you, but it didn't work. It cd'ed to the correct directory, but the prompt stayed "xplinux557@bash-pc:~ $". It didn't change at all. (Although I gotta give you props for stopping that annoying error message it gave me :)
xplinux557
YES! It worked! Except for one slight problem, though: when I cd outside of the user directory, the path is no longer in UNIX form; it shows up as:"xplinux557@bash-pc:C:\Program Files\NetBeans $"
xplinux557
I see this is the accepted answer. In my opinion, using CALL SET (see http://stackoverflow.com/questions/2394208/batch-scripting-question-search-and-replace-a-variable-in-a-variable/2394291#2394291) is simpler and clearer than using a setlocal/endlocal pair. It's one line instead of 3. Setlocal/endlocal has its place, but it is usually NOT to bracket a single line of code.
Cheeso
It's okay. I merged bits of your solution and Johannes' solution together and I got it! I used Johannes' method with the delayed expansion, since it is the technique that worked for me, but used your technique with managing the variables more efficiently.Thanks a lot to both of you!
xplinux557
@Cheeso: Thanks for that hint. Either I'm too tired right now or I didn't know about it yet. I used `call` only for batch files and subroutines so far.
Joey
A: 

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.

Cheeso
:eagerly coding as i type:Actually, I do want cd because the script called to change directories to upath (what the user typed in) and then get the full, complete Windows-style path that cd is in and replace the home folder with "~".Anyway, I'll reply and let you know how it goes.
xplinux557
You don't want %CD% because the slashes are facing the wrong direction. I'm assuming %unixhome% holds /users/Fred (fwd slash). In that case the substitution will never happen. So I think you want %cd:\=/%. I understand that may not be the same as upath in your case, because of relative-vs-full paths.
Cheeso
Thanks, but unfortunately, when I tried your code, the same thing happened as when I Johannes Rössel's code (scroll down to see my comment).PS: "unixhome" is probably a pretty bad name for this var :P It holds the main home directory, Windows-style and upath4 holds the Unix-style. I should have probably switched those two around. Sorry for being unclear
xplinux557
Yes, you get that error ( the path is no longer in UNIX form) because you are using %CD%. That's what I've been trying to tell you. I updated my code to show you more clearly what I mean. Have a second look. Also - I've used different variable names to make it super clear.
Cheeso