sed delete number between single quotes - regex

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);

Related

sed replace AFTER match and retain

I've been racking my brains for hours on this, but it seems simple enough. I have a large list of strings similar to the ones below and would like to replace the hyphens only after the comma, to commas:
abc-d-ef,1-2-3-4
gh-ij,1-2-3-4
to this
abc-def,1,2,3,4
gh-ij,1,2,3,4
I can't use s/-/,/2g to replace from second occurrence as the data differs, and also though about using cut, but there must be a way to use sed with something like:
"s/\(,\).*-/\1,&/g"
Thank you
This is more suitable for awk as we can break all lines using comma as field separator:
awk 'BEGIN{FS=OFS=","} {gsub(/-/, OFS, $2)} 1' file
abc-d-ef,1,2,3,4
gh-ij,1,2,3,4
If you want sed solution only then use:
sed -E -e ':a' -e 's/([^,]+,[^-]+)-/\1,/g;ta' file
abc-d-ef,1,2,3,4
gh-ij,1,2,3,4
An awk proposal.
awk -F, '{sub(/d-ef/,"def")gsub(/-/,",",$2)}1' OFS=, file
abc-def,1,2,3,4
gh-ij,1,2,3,4

Get specific Text between Specific Tags

At the top of my HTML files, I have...
<H2>City</H2>
<P>Liverpool</P>
or
<H2>City</H2>
<P>Dublin</P>
I want to output the text between the tags straight after <H2>City</H2> instances. So in the examples above which are separate files, I want to print out Liverpool and in the second example, Dublin.
Looking at this thread, I try:
sed -e 's/City\(.*\)\/P/\1/'
which I hope would get me half way there... but that just prints out the entire file. Any ideas?
awk to the rescue! You need multi-char RS support though (gawk has it)
$ awk -F'[<>]' -v RS='<H2>City</H2>' 'NF{print $3}' file
another approach can be
$ awk 'c&&c--{sub(/<[^>]*>/,""); print} /<H2>City<\/H2>/{c=1}' file
find the next record after City and trim the angle brackets...
Try using the following regex :
(?s)(?<=City<\/H2>\n<P>).*?(?=<\/P>)
see regex demo / explanation
sed
sed -e 's/(?s)(?<=City<\/H2>\n<P>).*?(?=<\/P>)/'
I checked and the \s seem not work for spaces. You should use the newline character \n:
sed -e 's/<H2>City<\/H2>\n<P>\(.*\)<\/P>/\1/'
There is no need of use lookbehind (like above), that is an overkill.
With sed, you can use the n command to read next line after your pattern. Then just remove the tag to output your content:
sed -n '/<H2>City<\/H2>/n;s/ *<\/*P> *//gp;' file
I think this should work in your mac:
echo -e "<H2>City</H2>\n<P>Dublin</P>" |awk -F"[<>]" '/City/{getline;print $3}'
Dublin

How to pass a variable from bash to 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>

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 replace a whole line with sed?

Suppose I have a file with lines
aaa=bbb
Now I would like to replace them with:
aaa=xxx
I can do that as follows:
sed "s/aaa=bbb/aaa=xxx/g"
Now I have a file with a few lines as follows:
aaa=bbb
aaa=ccc
aaa=ddd
aaa=[something else]
How can I replace all these lines aaa=[something] with aaa=xxx using sed?
Try this:
sed "s/aaa=.*/aaa=xxx/g"
You can also use sed's change line to accomplish this:
sed -i "/aaa=/c\aaa=xxx" your_file_here
This will go through and find any lines that pass the aaa= test, which means that the line contains the letters aaa=. Then it replaces the entire line with aaa=xxx. You can add a ^ at the beginning of the test to make sure you only get the lines that start with aaa= but that's up to you.
Like this:
sed 's/aaa=.*/aaa=xxx/'
If you want to guarantee that the aaa= is at the start of the line, make it:
sed 's/^aaa=.*/aaa=xxx/'
sed -i.bak 's/\(aaa=\).*/\1"xxx"/g' your_file
If you would like to use awk then this would work too
awk -F= '{$2="xxx";print}' OFS="\=" filename
This might work for you:
cat <<! | sed '/aaa=\(bbb\|ccc\|ddd\)/!s/\(aaa=\).*/\1xxx/'
> aaa=bbb
> aaa=ccc
> aaa=ddd
> aaa=[something else]
!
aaa=bbb
aaa=ccc
aaa=ddd
aaa=xxx