Search string for trailing quote character and trim it? - windows

I'm trying to search a string (entered by the user when prompted for a path) for a trailing quote and delete it if found.
The problem: I have a bat file that prompts the user to enter a filename and path (the first is typically done via drag/drop.) If the user enters a destination path enclosed in quotes because it contains spaces, my resulting command will look like this: compress.exe "c:\source path\"destination.zip"
That extra quote in the middle needs to go. I've found plenty of ways to search a file for a string, and I found this post here on StackOverflow that seems to apply, but doesn't seem to work in my situation.
I tried the command at the above linked path, telling it to search for \" instead of bcd, but the code expects the string it's searching to have been passed to it (as a switch) upon execution, and when I try to modify the command to search srcpath instead, the bat fails. I also tried this:
if "!srcpath:~-1"=="\"" set srcpath=!srcpath:~0,-1!
This results in: "The syntax of the command is incorrect."
How can I search a string for a trailing quote and trim it? Every method I can find doesn't seem to work when the character being searched for is the quote (slash quote: \").

I use a SLOPPY batch trick when working with paths just for this reason.
There are more elegant ways but this works just as well and I don't ever have to remember how I pulled it off.
First of all, 90% of the time.. we just want ALL quotes stripped.. that would just be:
set srcpath=%srcpath:"=%
Then tack quotes on to the front and back of your new concatenated path string.
But if you REALLY only want the trailing one.. here is my stupid bash trick..
1. Add a "? to the end of your string
2. Then delete ""? from that string
3. Then delete "? from that string
Wella! Never fails!
The trick here is that a question mark isn't a valid path char.
:: SAMPLE -- Just a trailing quote removed
set srcpath="c:\source path\"
set srcpath=%srcpath%"?
set srcpath=%srcpath:""?=%
set srcpath=%srcpath:"?=%
echo srcpath=%srcpath%
::You can use the SAME TRICK to remove a trailing backslash

Would this work for you?
SET /P "%SRCPATH=Enter the source path "
ECHO %SRCPATH%
ECHO %SRCPATH:"=%

Related

How to escape the special characters in a password when using in CMD

I have this password, ;d#se#&4~75EY(H[SM"%cznGB.
I need to use this inside an automatically created command line command.
(using it for TFS Release pipeline, to create a virtual directory and this password belongs to a service user and saved in a global variable as secret input, and TFS puts that password string in doublequotes when creating the command).
Having a hard time escaping the scpecial characters in it.
What I tried so far is to escape all alphanumeric characters by ^ and escaping % and " characters by doubling them. But so far, didn't have much luck :(
The list of failed attempts are these.
;d#se#&4~75EY^(H[SM""%%cznGB
;d#se#&4~75EY(H[SM\"%%cznGB
^;d^#se^#^&4^~75EY^(H^[SM""%%cznGB
^;d^#se^#^&4^~75EY^(H^[SM\"^%cznGB
^;d^#se^#^&4^~75EY^(H^[SM\"%%cznGB
^;d^#se^#^&4^~75EY^(H^[SM""^%%cznGB
;d#se#&4~75EY(H[SM"^^^%%cznGB
;d#se#&4~75EY(H[SM"^^^^%%cznGB
;d#se#&4~75EY(H[SM^""^%%cznGB
^;d^#se^#^&4^~75EY^(H^[SM^""^%%cznGB
^;d^#se^#^&4^~75EY^(H^[SM^""%%cznGB
;d#se#&4~75EY(H[SM""%%cznGB
Can you please give me a hand finding the correct escaped string to use it in a batch or in CMD as an inline command?
Before anyone downvotes this question because I posted a password, I edited many parts of it before posting. Just saying :)
UPDATE:
As I mentioned in the question, TFS creates a command text to set the virtual folder access credentials to IIS, for a specific web application. The log shows the command text like this.
"C:\WINDOWS\system32\inetsrv\appcmd.exe" set vdir /vdir.name:"appfolder/Files" -physicalPath:"\\servername\virtualfolder" -userName:"sa_user#domain.com" -password:";d#se#&4~75EY(H[SM"%cznGB"
(I entered the password as it is, for this output)
How interesting this all character escaping thing works!
I continued serching, and read everything I could find. The result is that all that should be escaped with in double quotes, are the double quotes themselves...
(correct me if there's something I am missing, that was correct for my case)
The resulting string that should be used in the TFS variable (and I tested it, it works!) is this:
;d#se#&4~75EY(H[SM""%cznGB
The only thing I added to the original password was another double quote near the double quote.
That answer certainly helped me. No wonder why experementing by yourselves preserves better than reading tons of articles :/
https://stackoverflow.com/a/15262019/2443719
Thanks to everyone who commented and left an answer to this thread.
rem // enable delayed expansion to expand other poison characters safely
#Echo off & setlocal EnableExtensions EnableDelayedExpansion
rem // escape % character by doubling
Set "PW=;d#se#&4~75EY(H[SM"%%cznGB"
"C:\WINDOWS\system32\inetsrv\appcmd.exe" set vdir /vdir.name:"appfolder/Files" -physicalPath:"\\servername\virtualfolder" -userName:"sa_user#domain.com" -password:"!PW!"
Endlocal

BASH function for escaping spaces in filenames before opening them

I've been trying to write a function for my bash profile for quite some time now.
The problem I'm trying to overcome is I'm usually provided with file paths that include spaces and it's a pain having to go through and escape all the spaces before I try to open it up in terminal.
e.g.
File -> /Volumes/Company/Illustrators/Website Front Page Design.ai
What I'm trying to end up with is '/Volumes/Company/Illustrators/Website\ Front\ Page\ Design.ai' being opened from my terminal.
So far I've managed to escape the spaces out, but I then get the error "The file ..... does not exist."
My code so far is
function opn { open "${1// /\\ }";}
Any help would be very much appreciated.
The important thing to understand is the difference between syntax and literal data.
When done correctly, escaping is syntax: It's read and discarded by the shell. That is, when you run
open "File With Spaces"
or
open File\ With\ Spaces
or even
open File" "With\ Spaces
...the quoting and escaping is parsed and removed by the shell, and the actual operating system call that gets executed is this:
execv("/usr/bin/open", "open", "File With Spaces")
Note that there aren't any backslashes (or literal quotes) in that syscall's arguments! If you put literal backslashes in your data, then you cause this to be run:
/* this is C syntax, so "\\" is a single-character backslash literal */
execv("/usr/bin/open", "open", "File\\ With\\ Spaces")
...and unless there's a file with backslashes in its name, that just doesn't work, giving the "file does not exist" error you report.
So -- just call open with your name in quotes:
open "$1"
...there's no need for an opn wrappper.
Spaces are problematic in filenames because they're part of bash's default IFS (Internal Field Separator), which is used to separate tokens in a command line. That means that by default, when you use command an argument with spaces, the command will receive 4 arguments rather than 1 containing spaces.
I'm guessing you called your opn function in the same way, thus resulting in only the first part of your path as $1.
Hopefully, the fix is easy : enclose your path in quotes so that bash does not interpret the spaces. By using this, the need for your opn function disappears : open "/Volumes/Company/Illustrators/Website Front Page Design.ai" should work just fine.

What does this Windows bat command mean?

I read the following command from the batch file to run Maven on Windows mvn.bat:
if not "_%M2_HOME:~-1%"=="_\" goto checkMBat
And
if "%#eval[2+2]" == "4" goto 4NTArgs
What does this batch script mean?
ADD 1
As I tried, it seems _%M2_HOME:~-1% returns the _ plus the last 1 letter of the environment variable "_%M2_HOME%. But what's the name of this syntax?
%VAR:~-1% gets the last character in the envvar. The first snippet verifies that the envvar M2_HOME doesn't end with \. Note: Maven's docs say,
Note: For Maven 2.0.9, also be sure that the M2_HOME doesn't have a '\' as last character.
This might be related. They probably want to prepend M2_HOME to subdir names and always include a dirsep. The variable substitution in "_%...%" is unaffected by the initial underscore. Experessing it that way just ensures that the underscore is at the beginning of the output. I can't say for certain, but it may have been expressed that way to avoid a backslashed quote, e.g. "\".
The second is not any CMD/batch that I'm familiar with. The comment (assuming this comes from mvn.bat) says "4NT shell", which I take to mean that this batch file could be run in the Take Command Console which probably has extensions to MS CMD features. For example, %#eval[...] probably does numeric evaluation in 4NT. This would effectively be a check to see if the script were running in a 4NT shell.
The first one takes the last character of %M2_HOME%, adds an underscore to the front, and checks to see if the resulting string is _\ - in short, it checks that the last character of %M2_HOME% is a backslash by using substrings.
The second one is how you determine if 4NT is installed on your computer; if it is, there will be a variable function called #eval.
I found the explanation to "_%M2_HOME:~-1%" below link. It's a variable substring operation.
http://ss64.com/nt/syntax-substring.html

Shortcut in nano editor for adding quotation marks to every word beginning with $ in a bash script?

I am new to writing in bash and I just finished this long script but I made the mistake of not adding quotation marks to all the variables beginning with the unary operator $. Adding all the quotation marks by hand is going to take a while. Is there a short cut I can use so all the words in the text file beginning with $ get quotation marks around them? So if a line in the file looks like:
python myProgram.py $car1 $car2 $speed1 $speed2
Then after the shortcut it will appear as
python myProgram.py "$car1" "$car2" "$speed1" "$speed2"
I am writing the script using nano.
Use global search and replace with the expression (\$\w+).
Switch to search and replace mode with C-\.
Switch to regex mode with Alt-R.
Type the expression (\$\w+). Hit Enter.
Type in the replacement expression "\1" replace the captured expression with quotations. Hit Enter.
On the match, hit A for All.
Given your need, it doesn't seem mandatory to provide a solution based on that editor. If you have access to a shell you might try this simple sed command:
sed -i.bak -r 's/\$\w+/"&"/g' my-script.sh
This is far from being perfect but should do the job in your particular case. If the above command:
-i.bak will perform the replacement "in place" -- that is modifying the original file, making a backup with the .bak extension
s/..../..../g is the usual sed command to search and replace using a pattern. The search pattern is between the first two \. The replacement is between the last two /
\$\w+ this pattern correspond to a $ followed by one or more letters (\w+). The backslash before $ is needed because that character normally has special meaning in a search pattern.
"&" is the replacement string. In there, the & is replaced by the string found in the search pattern. Broadly speaking this put quotes arround any string matching the search pattern.

Absolute path in perl's copy command gone wrong?

This is my very simple code, which isn't working, for some reason I can't figure out.
#!/usr/bin/perl
use File::Copy;
$old = "car_lexusisf_gray_30inclination_000azimuth.png";
$new = "C:\Users\Lenovo\Documents\mycomp\simulation\cars\zzzorganizedbyviews\00inclination_000azimuth\lexuscopy.png";
copy ($old, $new) or die "File cannot be copied.";
I get the error that the file can't be copied.
I know there's nothing wrong with the copy command because if I set the value of $new to something simple without a path, it works. But what is wrong in the representation of the path as I've written it above? If I copy and past it into the address bar of windows explorer, it reaches that folder fine.
Tip: print out the paths before you perform the copy. You'll see this:
C:SERSenovodocumentsmycompsimulationrszzzorganizedbyviewsinclination_000azimuthexuscopy.png
Not what we wanted. The backslash is an escape character in Perl, which needs to be escaped itself. If the backslash sequence does not form a valid escape, then it's silently ignored. With escaped backslashes, your string would look like:
"C:\\Users\\Lenovo\\Documents\\mycomp\\simulation\\cars\\zzzorganizedbyviews\\00inclination_000azimuth\\lexuscopy.png";
or just use forward slashes instead – in most cases, Unix-style paths work fine on Windows too.
Here is a list of escapes you accidentally used:
\U uppercases the rest
\L lowercases the rest
\ca is a control character (ASCII 1, the start of heading)
\00 is an octal character, here the NUL byte
\l lowercases the next character.
If no interpolation is intended, use single quotes instead of double quotes.

Resources