How to pass a variable from bash to regex - regex

I'm trying to print only lines that contain the variable $foo. I've tried using double quotes and curly braces to no avail. What is the proper way to pass a shell variable to a regex in sed?
sed -n 's:\("${foo}".*$\):\1:p' file.txt

sed is overkill if you don't actually need to modify the matching lines. Just use grep:
grep "$foo" file.txt

Try the below sed command to print the lines which contains value assigned to the variable foo.
sed -n "/$foo/p" file

Using single quote you get the result like
$-pattern='foo'
$-sed 's/('$pattern'.*$)/<\1>/g'
fo
fo
foo
<foo>

Related

Sed works only without grouping

I have a file of the following format:
foo: ...
bar: ...
baz: ...
I want to delete all lines that start with bar, baz or goo. I could do a couple of seds in the following format:
sed '/^bar:.*$/d'
But I'd like to instead put all the possibilities in one. I thought this would work, but its not deleting the lines:
sed '/^(?:bar|baz|goo):.*$/d'
I also noticed that not even this works:
sed '/^(bar):.*$/d'
Which was surprising because I thought the capture group wouldn't actually change any behavior in the pattern matching.
you need to use extended regular expressions
sed -r '/^(bar):.*$/d'
And sed doesn't support perl regular expressions, so you should be using
sed -r '/^(bar|baz|foo):.*$/d'
without non capture group ?:
You can use:
sed '/^\(bar\|baz\|foo\):/d' file
Or with extended regex:
sed -r '/^(bar|baz|foo):/d' file

How to grep a shell variable to match end of line?

How can I match a bash variable in the end of the line?
The code below can do that for a number in the end:
grep '[0-9]$'
But in my case the number is a variable. I was hoping something like
grep '{$i}$'
where $i is my variable, would work, but no avail. I've tried with several single/double comma combinations but no sucess so far.
Thanks in advance.
You can use this grep:
grep "$i\$" file
OR:
grep $i'$' file
You have to use "double quoting" for variable expansion in shell.. use the following:
grep "$i\$" file
Use single quotes to make the $ work as end-of-line. If you want to grep with some variable also, use double and single quotes as below:
grep "$var"'$'

sed delete number between single quotes

I have a file like:
35.26660,129.0373,'207636');
35.26667,129.0375,'207636');
35.55555,129.0377,'207636');
I want to delete last number between single quotes and the corresponding comma. I want the result to be like:
35.26660,129.0373);
35.26667,129.0375);
35.55555,129.0377);
I tried to use sed, but I made a mistake and I cannot see what is the problem.
If I use command:
sed "s/'//g"
Then I delete only the quotes
If I use command:
sed "s/[0-9]//g"
Then I delete only number between single quotes.
Update #1:
Sorry, in few lines I have a more data like:
'abc', '123' 35.26660,129.0373,'207636');
You can use this sed:
sed -i.bak "s/,'[^']*'//" file
It gives:
35.26660,129.0373);
35.26667,129.0375);
35.55555,129.0377);
I would do:
sed "s/,'[^']*')/)/"
Using awk
awk -F\' '{$2="";sub(/, +/,"")}1' file
35.26660,129.0373);
35.26667,129.0375);
35.55555,129.0377);

how to select lines containing several words using sed?

I am learning using sed in unix.
I have a file with many lines and I wanna delete all lines except lines containing strings(e.g) alex, eva and tom.
I think I can use
sed '/alex|eva|tom/!d' filename
However I find it doesn't work, it cannot match the line. It just match "alex|eva|tom"...
Only
sed '/alex/!d' filename
works.
Anyone know how to select lines containing more than 1 words using sed?
plus, with parenthesis like "sed '/(alex)|(eva)|(tom)/!d' file" doesn't work, and I wanna the line containing all three words.
sed is an excellent tool for simple substitutions on a single line, for anything else just use awk:
awk '/alex/ && /eva/ && /tom/' file
delete all lines except lines containing strings(e.g) alex, eva and tom
As worded you're asking to preserve lines containing all those words but your samples preserve lines containing any. Just in case "all" wasn't a misspeak: Regular expressions can't express any-order searches, fortunately sed lets you run multiple matches:
sed -n '/alex/{/eva/{/tom/p}}'
or you could just delete them serially:
sed '/alex/!d; /eva/!d; /tom/!d'
The above works on GNU/anything systems, with BSD-based userlands you'll have to insert a bunch of newlines or pass them as separate expressions:
sed -n '/alex/ {
/eva/ {
/tom/ p
}
}'
or
sed -e '/alex/!d' -e '/eva/!d' -e '/tom/!d'
You can use:
sed -r '/alex|eva|tom/!d' filename
OR on Mac:
sed -E '/alex|eva|tom/!d' filename
Use -i.bak for inline editing so:
sed -i.bak -r '/alex|eva|tom/!d' filename
You should be using \| instead of |.
Edit: Looks like this is true for some variants of sed but not others.
This might work for you (GNU sed):
sed -nr '/alex/G;/eva/G;/tom/G;s/\n{3}//p' file
This method would allow a range of values to be present i.e. you wanted 2 or more of the list then use:
sed -nr '/alex/G;/eva/G;/tom/G;s/\n{2,3}//p' file

How to use regular expression in sed command

i have some strings with this pattern in some files:
domain.com/page-10
domain.com/page-15
....
and i want to replace them with something like
domain.com/apple-10.html
domain.com/apple-15.html
i have found that i can use sed command to replace them at a time but because after the numbers should something be added i guess i have to use regular expression to do it. but i don't know how.
sed -i.bak -r 's/page-([0-9]+)/apple-\1.html/' file
sed 's/page-\([0-9][0-9]*\)/apple-\1.html/' file > t && mv t file
Besides sed, you can also use gawk's gensub()
awk '{b=gensub(/page-([0-9]+)/,"apple-\\1.html","g",$0) ;print b }' file
sed -i 's/page-\([0-9]*\)/apple-\1.html/' <filename>
The ([0-9]*) captures a group of digits; the \1 in the replacement string references that capture and adds it as part of the replacement string.
You may want to use something like -i.backup if you need to keep a copy of the file without the replacements, or just omit the -i and instead use the I/O redirection method instead.
One more way to resolve the problem:
sed -i.bak 's/\(^.*\)\(page-\)\(.*\)/\1apple-\3.html/' Files
Here the searching patterns are stored and retrieved using references (\1, \2, \3).
This will work
sed 's/$/\.html/g' file.txt