How to replace a text pattern containing brackets? - search

I want to replace a specific instruction containing brackets with another instruction recursively in all the files.
For example,
mov r1, [r1, r2]
with
sub [r8, r9], r10
When I use
sed -i.bak "s/mov r1, [r1, r2]/sub [r8, r9], r10/g" file.S
it doesn't work.
How can I do that?

Two things.
You need to escape the brackets in the match expression, they have special meaning in regular expressions.
You should protect the sed script from shell expansion. Using double quotes forces expansions. Single quotes switches expansion off.
Thus:
's/mov r1, \[r1, r2\]/sub [r8, r9], r10/g'
While working out the correct script you can just skip the inline editing, maybe. Like so:
sed 's/mov r1, \[r1, r2\]/sub [r8, r9], r10/g' file.S

Try with escaped brackets 's/mov r1, \[r1, r2\]/sub \[r8, r9\], r10/g'.

Escaping the brackets -- [ ] -- in sed's substitute command will process your file the way you expect it to. Here is your command rewritten with the brackets escaped:
sed 's/mov r1, \[r1, r2\]/sub [r8, r9], r10/g' file.S

Related

How do I create files with special characters in Linux?

I am using the touch command to try and create a file with the name "\?$*'KwaMe'*$?\" (quotation marks included as part of the file name). However when I type touch "\?$*'KwaMe'*$?\" in the Terminal, it doesn't give me the result I am expecting. How can I create this file?
You need to escape special characters with the backslash symbol (\).
This command will create a file named "\?$*'KwaMe'*$?\":
touch \"\\\?\$\*\'KwaMe\'\*\$\?\\\"
Explanation
Double your \, like this: \\, so that your shell does not interpret the backslashes from your filename as escape characters.
Escape " and ', like this: \", \', so that your shell interprets the double quotes as part of the filename.
Escape $, like this: \$, otherwise your shell will think you're using a variable.
Escape ? and *, like this: \?, \*, to prevent filename expansion.

How to substitute text which has implicit meaning in vi

I have a C code in vi from which I want to replace the text "\n" with something else. Use of %s:\n:(anything else) isn't working. Is there any way to bypass this?
For example,a line in the code is: printf("Hello world\n");
In vi, I need to replace "\n" in the printf line with a full stop. Use of substitue command (%s:\n:.) will not work for "\n"
Please let me know what is the command to replace 'text' which also has some implicit meaning in vi (here \n is newline is vi as well).
Thanks in advance!
You need to escape the backslash in \n, like this:
%s:\\n:.

Command sed using g

I am new to Linux.
I was debugging some code. I encountered the following command:
PROGRAM_ID=$(echo $PROGRAM_ID|sed 's/-/,/g')
Can anybody explain what the g represents here?
I understand hyphen is being replaced with comma.
The /g flag means, perform the substitution globally on a line. Without that flag, only the first hyphen on every line would get substituted.
A better way with Bash would be
PROGRAM_ID=${PROGRAM_ID//-/,}
but if you have to be portable to Bourne shell in general, this replacement facility is not available.
(In which case you should take care to keep "$PROGRAM_ID" in double quotes in the echo.)
Its easy to see how g (global) works with these two example:
echo "test-one-two-three" | sed 's/-/,/g'
test,one,two,three
echo "test-one-two-three" | sed 's/-/,/'
test,one-two-three
Without the g it only replace the first hit.

Is there different between single quote and double quote in vim command mode?

In my vim, I can use :%!sed "s/^/ /", got the wrong output when I use :%!sed 's/^/ /' .
sed: -e expression #1, char 0: no previous regular expression
Is there differences between single quote and double quote in vim command mode?
In my sed, single quote is the same as double quote.
$ echo "wha012" | sed 's/w/haha/'
hahaha012
$ echo "wha012" | sed "s/w/haha/"
hahaha012
my system is xp+vim 7.3 for windows.
In my system:
[1] "c://cygwin/bin/ash.exe"
[2] "c://cygwin/bin/bash.exe"
[3] "c://cygwin/bin/dash.exe"
[4] "c://cygwin/bin/sh.exe"
if i set set shell=\"c:\cygwin\bin\sh.exe"\ -f in _vimrc,i get the new wrong messages:
sed command can not found.
Funny, when I try :%!sed "/^/ /" I get the same error message as when I use single quotes:
sed: 1: "/^/ /": invalid command code /
(This line replaces the content of my file.) I expect to get an error message there because, as #Birei pointed out, you left out the sed s command. This works as expected, with either single or double quotes:
:%!sed "s/^/ /"
#Birei is also right that you can use vim to do things like this, but I assume you have simplified the example from what you were really trying to do.
To answer the original question, Vim uses single quotes for literal strings. The only special character in a literal string is ' itself. Strings delimited with double quotes use \ to denote special character, such as `"\<Esc>".
:echo 'a''b' == "a'b"
:help expr-string
:help literal-string
my system is xp+vim 7.3 for windows
By default Vim uses cmd.exe to run :! commands on Windows, which behaves differently with regard to quoting from the POSIX shell that your s/w/haha/ examples suggest you've been testing with. Try something like
:set shell=\"C:\path\to\sh.exe\"\ -f
to tell it to use your POSIX shell instead. Or if you're using cygwin then try the cygwin version of vim instead of the Windows native one.
The difference is in the sed command, that lets interpolate variables when you execute it directly from the shell, like:
sed "s/$pattern/$replacement/"
but your problem is that you have to use a substitution command that begins with letter s, like:
:%!sed "s/^/ /"
Also you can have same behaviour inside vim without an external command, like:
:%s/^/ /

vim :gsearch (greplace plugin) escaping characters

I am using the greplace plugin for vim and am not sure how to escape brackets in a search.
I want to search for cookies[:parent] and have tried:
:Gsearch cookies[:parent] # returns nothing
:Gsearch cookies\[:parent\] # returns nothing
How should I be doing this?
Thanks
Try
Gsearch cookies\\\[:parent\\\]
or
Gsearch 'cookies\[:parent\]'
. If I understood correctly, shell invoked by :grep! invoked by :Gsearch gets string grep -n cookies\[:parent\] /dev/null (assuming grepprg option has default value) and thus your escapes are interpreted by shell that thinks they are for escaping [ in order to prevent glob expansion. But after globbing done by shell grep takes argument as a pattern, so you need to escape it for grep also and it is why I have three backslashes here: two are to make grep get a backslash and third to prevent glob expansion.
:Gsearch cookies\\\[:parent] works for me.
Remember that :Gsearch requires a file mask in addition to the pattern, so in reality, you'd want to type something like :Gsearch \\\[:parent] *.php or whatever, to specify which files you want to have searched.
:Gsearch cookies\[:parent]
[ is the start of a character class, so needs to be escaped. The ] isn't particularly special so doesn't need to be escaped.

Resources