Replace /**/ in Unix with an empty space - regex

I wanted to replace /**/ across all files in a folder. I tried:
perl -pi -w -e 's/\/**\///g;' *.java
But got an error: Nested quantifiers in regex; marked by <-- HERE in m//** <-- HERE // at -e line 1.
Same thing with:
sed 's/\/**\///g;'
I need to basically replace /**/ with an empty space.

You need to escape the asterisks as well. To preserve readability, you may want to use other delimiters as well:
sed "s#/\*\*/##g"

You can specify * within []:
perl -pi -w -e 's#/[*]{2}/# #g;' *.java
Alternatively, you can make use of quotemeta operator:
perl -pi -w -e 's#\Q/**/\Q# #g;' *.java
which escapes all ASCII characters not matching /[A-Za-z_0-9]/.

Related

Why does this regex work in grep but not sed?

I have two regular expressions:
$ grep -E '\-\- .*$' *.sql
$ sed -E '\-\- .*$' *.sql
(I am trying to grep lines in sql files that have comments and remove lines in sql files that have comments)
The grep command works using this regex; however, the sed returns the following error:
sed: -e expression #1, char 7: unterminated address regex
What am I doing incorrectly with sed?
(The space after the two hyphens is required for sql comments if you are unfamiliar with MySql comments of this type)
You're trying to use:
sed -E '\-\- .*$' *.sql
Here sed command is not correct because you're not really telling sed to do something.
It should be:
sed -n '/-- /p' *.sql
and equivalent grep would be:
grep -- '-- ' *.sql
or even better with a fixed string search:
grep -F -- '-- ' *.sql
Using -- to separate pattern and arguments in grep command.
There is no need to escape - in a regex if it is outside bracket expression (or character class) i.e. [...].
Based on comments below it seems OP's intent is to remove commented section in all *.sql files that start with 2 hyphens.
You may use this sed for that:
sed -i 's/-- .*//g' *.sql
The problem here is not the regex, the problem is that sed requires a command. The equivalent of your grep would be:
sed -n '/\-\- .*$/p'
You suppress output for non-matching lines -n ... you search (wrap your regex in slashes) and you print p (after the last slash).
P.S.: As Anub pointed out, escaping the hyphens - inside the regex is unnecessary.
You are trying to use sed's \cregexpc syntax where with \-<...> you are telling sed the delimiter character you want use is a dash -, but you didn't terminate it where it should be: \-<...>- also add d command to delete those lines.
sed '\-\-\-.*$-d' infile
see man sed about that:
\cregexpc
Match lines matching the regular expression regexp. The c may be any character.
if default / was used this was not required so:
sed '/--.*$/d' infile
or simply:
sed '/^--/d' infile
and more accurately:
sed '/^[[:blank:]]*--/d' infile

perl regex find and replace with variable from bash

I have this regex: 'src=\d' which match all src attributes who start with a number in a file. I need to store it within a variable, cut src= out and write from there a new $string with \d concatenated to it: $string . $d. Is it possible to store only \d in a variable with a single command line? How to use cut and variable in a command line with perl? Is it possible?
perl -pi -w -e 's/src="\d+/src="http:\/\/website.com\/\d+/g’ file.tsv
I'm not exactly sure what you mean, but I think you want something like this, where the () brackets store the number and the $1 replaces it back.
perl -pi -w -e 's/src="(\d+)/src="http:\/\/website.com\/$1/g’ file.tsv
And you can avoid the so-called 'leaning toothpick syndrome by selecting a different delimiter for the s/// operation like s{}{}
perl -pi -w -e 's{src="(\d+)}{src="http://website.com/$1}g’ file.tsv

Complex Find and Replace in unix command line

I'm trying to do a complex find and replace in all files through unix command line using the answer provided in find and replace in multiple files on command line but I can't seem to get my find and replace strings escaped properly.
I need to find all lines that contain:
if ($session['test']>0){
and replace it with
if ($session['test']>1){
The command I'm trying is:
find . -name '*.php' |xargs perl -pi -e 's/if\(\$session\[\'test\'\]\>0\){/if\(\$session\[\'test\'\]\>1\){/g'
But that gives me another prompt which requires me to enter an additional ' character because the command tells me there's a string that's missing termination. If I put it in extra ' at the end, I get:
Unmatched ) in regex; marked by <-- HERE in m/if\(\$session\[\test']>0) <-- HERE {/ at -e line 1.
How do I get this replacement to work?
Just use double quotes:
perl -pi -e "s/if\(\$session\[\'test\'\]\>0\){/if\(\$session\[\'test\'\]\>1\){/g"
Moreover, you are missing a space after if and the dollar sign needs to be escaped with three backslashes:
perl -pi -e "s/if \(\\\$session\[\'test\'\]\>0\){/if \(\\\$session\[\'test\'\]\>1\){/g"
^ ^^^ ^^^
Using double quotes and double escaping the $ works:
perl -pi -e "s/if \(\\\$session\['text'\]>0\){/if (\\\$session['text']>1){/"
A shorter but dirtier solution with a look-behind and look-ahead assertions:
perl -pi -e 's/(?<=if \(\$session\[.text.\]>)0(?=\){)/1/'

Find and replace text with slash characters

So I looked around on Stackoverflow and I understand finding and replacing text works something like this:
perl -pi -w -e 's/www.example.com/www.pressbin.com/g;' *.html
However, what if the text I want to find and replace is a filepath that has slashes? How do I do it then?
perl -pi -w -e 's/path/to/file/new/path/to/file/g;' *.html
With perl regexes, you can use any character except spaces as regex delimiter, although
Characters in \w (so s xfooxbarx is the same as s/foo/bar/) and
Question marks ? (implicitly activates match-only-once behaviour, deprecated) and
single quotes '...' (turns of variable interpolation)
should be avoided. I prefer curly braces:
perl -pi -w -e 's{path/to/file}{new/path/to/file}g;' *.html
The delimiting character may not occur inside the respective strings, except when they are balanced braces or properly escaped. So you could also say
perl -pi -w -e 's/path\/to\/file/new\/path\/to\/file/g;' *.html
but that is dowrnright ugly.
When using braces/parens etc there can be whitespace between the regex and the replacement, allowing for beatiful code like
$string =~ s {foo}
{bar}g;
Another interesting regex option in this context is the quotemeta function. If your search expression contains many characters that would usually be interpreted with a special meaning, we can enclose that string inside \Q...\E. So
m{\Qx*+\E}
matches the exact string x*+, even if characters like *, '+' or | etc. are included.
You can use other characters than '/' to specify patterns. For example:
perl -pi -w -e 's,path/to/file,new/path/to/file,g;' *.html
perl -pi -w -e 's/path\/to\/file/new\/path\/to\/file/g;' *.html

Perl regex: remove everything (including line breaks) until a match is found

Apologies for the simple question. I don't clean text or use regex often.
I have a large number of text files in which I want to remove every line until my regex finds a match. There's usually about 15 lines of fluff before I find a match. I was hoping for a perl one-liner that would look like this:
perl -p -i -e "s/.*By.unanimous.vote//g" *.txt
But this doesn't work.
Thanks
Solution using the flip-flop operator:
perl -pi -e '$_="" unless /By.unanimous.vote/ .. 1' input-files
Shorter solution that also uses the x=!! pseudo operator:
per -pi -e '$_ x=!! (/By.unanimous.vote/ .. 1)' input-files
Have a try with:
If you want to get rid until the last By.unanimous.vote
perl -00 -pe "s/.*By.unanimous.vote//s" inputfile > outputfile
If you want to get rid until the first By.unanimous.vote
perl -00 -pe "s/.*?By.unanimous.vote//s" inputfile > outputfile
Try something like:
perl -pi -e "$a=1 if !$a && /By\.unanimous\.vote/i; s/.*//s if !$a" *.txt
Should remove the lines before the matched line. If you want to remove the matching line also you can do something like:
perl -pi -e "$a=1 if !$a && s/.*By\.unanimous\.vote.*//is; s/.*//s if !$a" *.txt
Shorter versions:
perl -pi -e "$a++if/By\.unanimous\.vote/i;$a||s/.*//s" *.txt
perl -pi -e "$a++if s/.*By\.unanimous\.vote.*//si;$a||s/.*//s" *.txt
You haven't said whether you want to keep the By.unanimous.vote part, but it sounds to me like you want:
s/[\s\S]*?(?=By\.unanimous\.vote)//
Note the missing g flag and the lazy *? quantifier, because you want to stop matching once you hit that string. This should preserve By.unanimous.vote and everything after it. The [\s\S] matches newlines. In Perl, you can also do this with:
s/.*?(?=By\.unanimous\.vote)//s
Solution using awk
awk '/.*By.unanimous.vote/{a=1} a==1{print}' input > output