I've been using doxygen for a little while now. The editor(N++) I use creates doxygen comments with backslashes for the special commands.
The doxygen manual says:
All commands in the documentation start with a backslash ( \ ) or an at-sign ( # ). If you prefer you can replace all commands starting with a backslash below by their counterparts that start with an at-sign.
So doxygen doesn't really care about it.
Or causes using a \ more trouble than using an #.
The backslash is used as an escape character in C/C++, so that '\"' is a double quote character for example.
Using # for doxygen tags makes it easier to use grep / search the source code.
I always use # for this reason.
Related
I'm aware that, in PowerShell, backticks(`) are used to escape characters instead of the backslash(\). Hence, when using sed, this:
echo '"where am I"' | sed "s/\"[^\"]*\"/\033[96m&\033[0m/g;"
will not work and I would have to write it like this:
echo '"where am I"' | sed "s/`"[^\`"]*`"/`e[96m&`e[0m/g;"
Hence, I would like to do the same with this code:
echo '[where am I]' | sed "s/\[\([^09]\)/\033[94m[\033[0m\1/g;"
The expected output should be:
However, when I tried to replace all the backslashes(\) with backticks(`), I can't seem to get the expected output as you can see below:
Any help would be appreciated. Thanks in advance.
As far as I'm aware, GNU sed doesn't support octal escape sequences - such as \033 to represent an ESC char. - only hexadecimal ones - such as \x1b.
The following command, which uses hex. escape sequences, should therefore work in both POSIX-compatible shells and in PowerShell:
# Note: Requires *GNU* sed
(echo '[where am I]' | sed 's/\[\([^09]\)/\x1b[94m[\x1b[0m\1/g')
In other words:
Because the entire, verbatim string ('...') is interpreted by sed itself, there is no need for PowerShell's string interpolation (via "...").
Note:
The enclosing (...), which on Windows is required for Windows PowerShell to properly render the ANSI escape codes / VT (Virtual Terminal) sequences in the terminal (console) - see this answer. It isn't needed if you capture the output in a variable or redirect it.
In PowerShell, use of echo - a built in alias of the Write-Output cmdlet - isn't necessary and can be omitted, due to PowerShell's implicit output behavior.
If your sed implementation doesn't support escape sequences such as \x1b - such as on macOS - you must indeed resort to using PowerShell's escape sequences inside an expandable (double-quoted) string ("..."); that is, you must replace \x1b with escape sequence `e in order to embed a verbatim ESC character into the string, up front (in Windows PowerShell, which doesn't support `e, use subexpression $([char] 0x1b) instead):
# Note: `e only works in PowerShell (Core) 7+
# In Windows PowerShell, use $([char] 0x1b)
(echo '[where am I]' | sed "s/\[\([^09]\)/`e[94m[`e[0m\1/g")
Important: The above commands contain no embedded " characters, which avoids a long-standing PowerShell bug that is still present as of PowerShell (Core) 7.2.2:
The need to unconditionally, manually \-escape embedded " chars. in arguments passed to external programs - see this answer for details.
A few quick examples that print verbatim 3" of snow:
# Up to at least PowerShell 7.2.2:
# Without escaping the embedded " with \ (too),
# they would in effect be removed from the arguments.
# Note that pipeline input is *not* affected.
'3" of snow' | findstr '\"' # Windows
/bin/echo '3\" of snow' # Unix
# In expandable (double-quoted) strings, you therefore must escape *twice*:
# once for PowerShell, then for the external-program call.
'3" of snow' | findstr "\`"" # Windows
/bin/echo "3\`" of snow" # Unix
You can pass non-interpolated expression strings to sed by using single quotes, '; e.g., 'a non-interpolated string'. instead of double quotes around the text. sed would take what it normally does for input. When you use double quotes, that's when powershell escaping comes into play.
Anyway, an alternative to sed would be leveraging the regular expression substitution built into powershell. For instance,
Write-Output ('[where am i]' -replace '\[(.*?)\]', "<<`e[5;36m`$1`e[0m>>")
Will capture the text between square brackets and place it between "chevrons" and make it blink.
Here's an article on inserting ANSI in text using powershell.
I am trying to use a sed command to replace specials characters in my file.
The characters are %> to replace by ].
I'am using sed -r s/\%>\/\]\/g but i have this error bash: /]/g: No such file or directory, looks like sed doesn't like it.
Put your sed code inside quotes and also add the file-path you want to work with and finally don't escape the sed delimiters.
$ echo '%>' | sed 's/%>/]/g'
]
ie,
sed 's/%>/]/g' file
To complement Avinash Raj's correct and helpful answer:
Since you were using an overall unquoted string (neither single- nor double-quoted), you were on the right track by \-escaping individual characters in your sed command.
However, you neglected to \-quote >, which is what caused your problem:
> is one of the shell's so-called metacharacters
Metacharacters have special meaning and separate words
Thus, s/\%>\/\]\/g is mistakenly split into 2 arguments by >:
s/\% is passed to sed - as s/%, because the shell removes the \ instances (a process called quote removal).
As you can see, this is not a valid sed command, but that doesn't even come into play - see below.
>\/\]\/g is interpreted by the shell (bash), because it starts with output-redirection operator >; after quote removal, the shell sees >/]/g, tries to open file /]/g for writing, and fails, because your system doesn't have a subdirectory named ] in its root directory.
bash tries to open an output file specified by a redirection before running the command and, if it fails to open the file, does not run the command - which is what happened here:
bash complained about the nonexistent target directory and aborted processing of the command - sed was never even invoked.
Upshot:
In a string that is neither enclosed in single nor in double-quotes, you must \-quote:
all metacharacters: | & ; ( ) < > space tab
additionally, to prevent accidental pathname expansion (globbing): * ? [
Also note that if you need to quote (escape) characters for sed,you need to add an extra layer of quoting; for instance to instruct sed to use a literal . in the regex, you must pass \\. - two backslashes - so that sed sees the properly escaped \..
Given the above, it is much simpler to (habitually) use single quotes around your sed command, because it ensures that the string is passed as is to sed.
Let's compare a working version of your command to the one from Avinash Raj's answer (leaving out the -r for brevity):
sed s/\%\>\/\]\/g # ok - all metachars. \-quoted, others are, but needn't be quoted
sed s/%\>/]/g # ok - minimum \-quoting
sed 's/%>/]/g' # simplest: single-quoted command
I'm not sure whether I got the question correctly. If you want to replace either % or > by ] then sed is not required here. Use tr in this case:
tr '%>' ']' < input.txt
If you want to replace the sequence %> by ] then the sed command as shown by #AvinashRaj is the way to go.
I'm using zsh, and am trying to write a function to operate on a URL and a pathname:
function my-function
{
somecommand --url $1 $(readlink -f $2)
}
(to complicate things somewhat, the function actually uses sh syntax, as it is sourced from my ~/.zshrc using a trick like this). The readlink is there to expand symlinks and ensure directories such as . are evaluated correctly (the directory name is stored for later use by somecommand).
When I type a command from the command-line like this:
my-function http://example.org/example /tmp/myexampledirectory
... it works fine, even if I autocomplete the directory name. However, if the directory name contains spaces, zsh completes it like this:
my-function http://example.org/example /tmp/My\ Example\ Directory
For most "normal" commands (cp, mv, etc.) that never seems to cause a problem. However, in my case, somecommand sees $2 as only being /tmp/My - presumably the rest is seen as another argument.
How can I avoid this situation? I would prefer not to alter the standard zsh autocompletion, but rather find a way for my function to handle this.
The zsh completion system works very well here, and the solution is very simple, just put double-quotes around the readlink argument in the script:
somecommand --url $1 $(readlink -f "$2")
The point is that without quotes readlink removes backslashes which escape whitespaces. Compare three results:
1. Without backslashes and quotes readlink -f assumes that there are three different files/directories (with default path in current directory) and produces
$ readlink -f /tmp/My Example Directory
/tmp/My
/home/jimmij/Example
/home/jimmij/Directory
2. With escaping backslashes but without quotes readlink -f understands that there is only one directory, but removes backslashes from output, so that somecommand takes three separate arguments
$ readlink -f /tmp/My\ Example\ Directory
/tmp/My Example Directory
3. With backslashes and with double-quotes readlink -f gives the output with backslashes what is (most probably) expected by somecommand
$ readlink -f "/tmp/My\ Example\ Directory"
/tmp/My\ Example\ Directory
BTW, as a rule of thumb: if there are any problems with whitespaces in the shell-like scripts (bash, zsh, whatever) the first thing to play with is different quotation marks around variables.
I'm trying to pass a JSON string from within a powershell script to the build.phonegap.com api, using curl.
According to phonegap's forum, when running on a Windows machine, the JSON data has to be formatted as:
curl.exe -ku user#email:mypass -X PUT -d "data={\"password\":\"keypass\"}" https://build.phonegap.com/api/v1/key
Indeed, this does run fine when invoked from the command line.
However, when I try to invoke this from within a powershell script, the double quotes seem to be stripped.
So far, I have tried:
Putting the JSON in single quoted string:
curl.exe -ku user#email:mypass -X PUT -d '"data={\"password\":\"keypass\"}"' https://build.phonegap.com/api/v1/key
Putting the JSON in single quoted string, without the DOS escape backslashes:
curl.exe -ku user#email:mypass -X PUT -d '"data={"password":"keypass"}"' https://build.phonegap.com/api/v1/key
Putting the JSON in single quoted string, escaping the double quotes and backslashes (DOS style with a backslash):
curl.exe -ku user#email:mypass -X PUT -d '\"data={\\\"password\\\":\\\"keypass\\\"}\"' https://build.phonegap.com/api/v1/key
Putting the JSON in a double quoted string, escaping the double quotes with the powershell backtick character (`):
curl.exe -ku user#email:mypass -X PUT -d "`"data={\`"password\`":\`"build*2014`\`"}`"" https://build.phonegap.com/api/v1/key
Any idea how to achieve this?
Thanks for your time,
Koen
Try using the --% operator to put PowerShell into simple (dumb) argument parsing mode:
curl.exe --% -ku user#email:mypass -X PUT -d "data={\"password\":\"keypass\"}" https://build.phonegap.com/api/v1/key
This is quite often useful for invoking exes with argument syntax that runs afoul of PowerShell's argument syntax. This does require PowerShell V3 or higher.
Update:
PowerShell 7.3.0 mostly fixed the problem, with selective exceptions on Windows, though a future version may requires opt-in - see this answer for details.
For cross-version, cross-edition code, the Native module discussed below may still be of interest.
tl;dr:
Up to at least PowerShell 7.2.x, manual \-escaping of " characters inside PowerShell strings is - unfortunately - required.
# From inside PowerShell:
# Note the outer '...' quoting and the unexpected need to escape
# the embedded " chars. as \" (unexpected, because PowerShell itself doesn't
# require " inside '...' to be escaped; also, PowerShell's escape char. is `).
# If outer "..." quoting must be used, use \`" (sic) to escape the embeded "
curl.exe -ku user#email:mypass -X PUT -d 'data={\"password\":\"keypass\"}' https://build.phonegap.com/api/v1/key
Read on for why that is necessary, and about a potential future fix.
PowerShell's escape character is ` (the so-called backtick), so in order to embed " characters in a "..." (double-quoted, interpolating) string, use `" (or "") rather than \"; by contrast, inside a '...' (single-quoted, verbatim) string, " need not be escaped.
In your attempt, PowerShell didn't see \" as an escaped " and therefore saw multiple "..." strings, which ultimately - when PowerShell of necessity applied its on demand re-quoting behind the scenes, passed two separate string arguments that individually didn't need double-quoting, due to not containing spaces, namely: verbatim data={\ and password\:\keypass\}
Using PowerShell's quoting rules, you should have used:
either:
"data={`"password`":`"keypass`"}"
or, more simply, given that no string interpolation is needed, via a verbatim, single-quoted string, inside of which " chars. don't require escaping:
'data={"password":"keypass"}'
Unfortunately, however, as of PowerShell 7.2.x this is NOT enough, though the experimental PSNativeCommandArgumentPassing feature available since PowerShell Core 7.2.0-preview.5 may fix this at least for some external programs, including curl.exe; read on for details.
As of PowerShell 7.2.x, an unexpected extra layer of escaping of embedded " characters is needed, using \-escaping when calling (most) external programs:
In Windows PowerShell there are edge cases where this approach doesn't work, in which case use of --% is required (see below). Notably, escaping '"foo bar"' as '\"foo bar\"' doesn't work, due to the enclosing \" being at the very start and end of the string - see this answer for details.
Also, some external programs on Windows understand ""-escaping only (e.g. msiexec); for them, use -replace '"', '""' in order to programmatically perform the extra escaping, assuming the value contains at least one space. Do the same for programs that do not support embedded " chars. at all (WSH), so that the embedded " at least do not break argument boundaries (but they will be stripped).
For programs that expect \"-escaping, use the following -replace operation to robustly perform the extra escaping programmatically:
'...' -replace '([\\]*)"', '$1$1\"'
If the input string contains no preexisting verbatim \" sequences, you can simplify to '...' -replace '"', '\"'
# Note: Escaping the embedded " chars. as `" is enough for PowerShell itself,
# but, unfortunately, not when calling *external programs*.
# The `-replace` operation performs the necessary additional \-escaping.
$passwd = 'foo'
curl.exe -ku user#email:mypass -X PUT -d (
"data={`"password`": `"$passwd`"}" -replace '([\\]*)"', '$1$1\"'
) https://build.phonegap.com/api/v1/key
This shouldn't be required, but is due to a bug since v1 that hasn't been fixed for fear of breaking backward compatibility - see this answer.
A - presumably - opt-in fix is now being considered for some future version, post v7.2 - see GitHub issue #14747 - and using it, once available, would obviate the need for the manual escaping.
Since PowerShell Core 7.2.0-preview.5, experimental feature PSNativeCommandArgumentPassing with an attempted fix is available, but, unfortunately, it looks like it will lack important accommodations for high-profile CLIs on Windows (though curl.exe wouldn't be affected) - see this summary from GitHub issue #15143.
A backward- and forward-compatible helper function is the ie function from the Native module (Install-Module Native), which obviates the need for the extra escaping, contains important accommodations for high-profile CLIs on Windows, and will continue to work as expected even with the opt-in fix in place:
ie curl.exe ... -d "data={`"password`": `"$passwd`"}" ... )
Using --%, the stop-parsing symbol, as in Keith Hill's answer is a suboptimal workaround that also doesn't require the extra \-escaping, however:
--% has inherent limitations - see GitHub docs issue #6149 - and is virtually useless on Unix-like platforms - see GitHub docs issue #4963.
The only - awkward and side effect-producing - way to embed PowerShell variable values in the arguments following --% is to (a) define them as environment variables (e.g., $env:passwd = 'foo') and (b) to reference these variables cmd.exe-style, even on Unix (e.g., %passwd%).
An alternative workaround - especially if you need to include the values of PowerShell variables or expressions in your calls - is to call via cmd /c with a single argument containing the entire command line; for quoting convenience, the following example uses a here-string (see the bottom section of this answer for an overview of PowerShell's string literals):
# Use #"<newline>...<newline>"# if you need to embed PowerShell variables / expressions.
cmd /c #'
curl.exe -ku user#email:mypass -X PUT -d "data={\"password\":"\keypass\"}" https://build.phonegap.com/api/v1/key
'#
Here's how I did manage to send a json request in PowerShell 7.2
Finally found the solution. Istead of using one " use 3 of them ("""), and thats it. So it would be:
data={"""password""":"""keypass"""}
Set the content type:
curl -H "Content-Type: application/json" -d '{"password":"keypass"}' https://build.phonegap.com/api/v1/key
I'm trying to replace a string, inside of a file, with perl from inside a Makefile.
InstallTo = $(PWD)/WebTest
BuildApache:
mkdir -p WebTest
cd Source/httpd; ./configure --prefix=$(InstallTo) --exec-prefix=$(InstallTo)
cd Source/httpd; make; make install
cd $(InstallTo)/conf; perl -pi -e 's/ServerRoot \"$(InstallTo)\"/ServerRoot/g' httpd.conf
cd $(InstallTo)/conf; cp -f httpd.conf httpd.conf.orig
I'm not sure exactly what I'm doing though, I've just tried to modify the perl line from something I found on the net. I think its the \" thats messing things up but I don't know enough about Perl to fix it.
You might want to try:
s|ServerRoot "$(InstallTo)"|ServerRoot|g
You're pasting a value with a slash in it as part of the search expression. It ends up as:
s/ServerRoot \"PWD/WebTest\"/ServerRoot/g
(Where PWD stands for any literal directory spec.) Since you can't escape the slash, that's always going to be a problem unless you use an alternative delimiter.
Since your variable contains '/' you need to use a different character for regular expressions, also you may want to use quotemeta or \Q..\E in regular expressions having variables which can contain special characters
s#\QServerRoot "$(InstallTo)"\E#ServerRoot#g
Refer to this post for more details how-do-i-handle-special-characters-in-a-perl-regex