How to replace part of a line with sed - sed

I want to replace the part of a line that doesn't match. For example I have a line from grep:
./XYZ/SportsDataManager.m:static NSString* REDEEM_SPORT_CREDIT_URL = #"http://example.com/clients/XYZ/services/sports/prod/prod_sportRedeemUserCredit.php";
From what I've read, it's best to pipe this through sed. I want to remove everything EXCEPT the url. How could this be done?

I would use egrep with -o, for example
echo "./XYZ/SportsDataManager.m:static NSString* REDEEM_SPORT_CREDIT_URL = #\"http://example.com/clients/XYZ/services/sports/prod/prod_sportRedeemUserCredit.php\";" | egrep 'http://.*?\.php' -o
http://example.com/clients/XYZ/services/sports/prod/prod_sportRedeemUserCredit.php

Using sed, if you always have URLs within double quotes:
sed -n 's/[^"]*"\([^"]*\).*/\1/p' input

Related

sed issue replacing a negative value

I have a file where some entries look like:
EMIG_BAD_ID = syscall.Errno( -0x12f)
I want to use sed to replace that negative number to make it positive,
EMIG_BAD_ID = syscall.Errno( 0x12f)
I've tried some ideas from web searches but not succeded.
E.g. this one exits with an error:
egrep EMIG_* _error.grep | \
sed -e 's/syscall.Errno(\1)/syscall.Errno(-\1)/g' _error.grep
sed: -e expression #1, char 40: Invalid back reference
What is wrong here?
If the format is exactly like you posted, you can use this fairly easy replacement:
sed 's/syscall.Errno( -/syscall.Errno( /g' _error.grep
To make the space between ( and - optional:
sed 's/syscall.Errno( \?-/syscall.Errno( /g' _error.grep
To answer your question / if you insist on using back references (and optional space), here's how to use back references:
sed 's/syscall.Errno( \?-\(.*\))/syscall.Errno(\1)/g' _error.grep
Some additional notes:
You don't need grep - if EMIG_BAD_ID is on the same line it's very easy to include that in the sed matching pattern.
You pipe from egrep to sed and let sed read from a file. That doesn't make sense. You should prefer reading files directly with sed; but if you need grep, just read from stdin (without the file argument). Specify -i with sed to perform an in-place edit.
Using sed
$ sed -E '/^EMIG/s/-([0-9]+)/\1/' input_file
EMIG_BAD_ID = syscall.Errno( 0x12f)
Thank you for your answers. Unfortunately I don't have a working answer yet.
Code below: (part of a bigger file)
cat _error.out
E2BIG = 0x40000007
EMIG_ARRAY_TOO_LARGE = -0x133
cat test.sh
cat _error.out | sed 's/=\(.*\)/= syscall.Errno(\1)/'
Result:
E2BIG = syscall.Errno( 0x40000007)
EMIG_ARRAY_TOO_LARGE = syscall.Errno( -0x133)
The problem is to use bash/grep/sed to make the negative number positive.
Thanks!

Parsing a string with sed

I have a string like prefix-2020.80-suffix-1
Here are all of possible combinations of input string
"2020.80-suffix-1"
"2020.80-suffix"
"prefix-2020.80"
"prefix-2020.80-1"
I need to cut out and assign 2020 to a variable but cannot get my desired output
Here what i got so far...
set var=`echo "prefix-2020.80-suffix-1" | sed "s/[[:alnum:]]*-*\([0-9]*\).*/\1/"`
My regexp does not work for other cases and i cannot figure out why! its more complicated that python's regexp syntax
This should work for all you inputs
sed 's/.*\(^\|-\)\([0-9]*\)\..*/\2/' test
Matches the start of the line or everything up to -[number]. and captures the number.
The problem with the original you were using was you didn't take into account when there wasn't a prefix.
You can use this grep -oP:
echo "prefix-2020.80-suffix-1" | grep -oP '^([[:alnum:]]+-)?\K[0-9]+'
2020
RegEx Demo
Using sed (with extended regex):
echo "prefix-2020.80-suffix-1" |sed -r 's/^([^-]*-|)([0-9]+).*/\2/'
Using grep:
echo "prefix-2020.80-suffix-1" |grep -oP "^([^-]*-|)\K\d+"
2020
-P is for Perl regex.

Sed command to fetch particular string from full string

I've got a file which contains lot of strings like below input.
Need to extract the below output and process it further.
Input:
History={ExecAt=[2013-05-03 03:00:20,2013-05-03 03:00:23,2013-05-03 03:00:26],MId=["msgId3","msgId4","msgId5"]};
Output should be:
MId=["msgId3","msgId4","msgId5"]
using (sed 's/^.*,MId=/MId/') command i got the output like MId=["msgId3","msgId4","msgId5"]};
but still wanted the exact output (need to remove last 2 special chars }; here).
This works for me:
sed 's/.*\(MId=.*\)\}.*/\1/'
If your grep supports the -o option, you can use it rather than sed:
grep -o 'MId=\[[^]]\+\]'
Using the same regex in sed works fine, just remove anything before and after:
sed -e 's/.*\(MId=\[[^]]\+\]\).*/\1/'

modify a line using sed

I need to used sed for following requirment using sed
I have one string as $str and I need to replace blow line in a file
abh{1..$abh} cdf_$ghu,xyz * abh{}.$xy
New modified line should be as below
abh{1..$abh} cdf_$ghu,$str * abh{}.$xy
Note "xyz" can be any arbitrary value. Could you please tell me how to do using sed in one liner.
sed 's/\(^\s*abh{1..$abh}\s*\)\(.*xyz\)/\1/' file.txt
but still does not work. Any help would be appreciated.
Try this:
$ sed 's|\(\S\+\s\+[^,]\+,\)\S\+\(\s\+.*\)|\1$str\2|' file.txt
abh{1..$abh} cdf_$ghu,$str * abh{}.$xy
Or even more simple:
$ sed 's|,\S\+|,$str|' example.txt
echo 'abh{1..$abh} cdf_$ghu,xyz * abh{}.$xy' | sed 's/\(.*\$ghu,\)\(.*\)\( .*\)/\1\$str\3/g'

How do I push `sed` matches to the shell call in the replacement pattern?

I need to replace several URLs in a text file with some content dependent on the URL itself. Let's say for simplicity it's the first line of the document at the URL.
What I'm trying is this:
sed "s/^URL=\(.*\)/TITLE=$(curl -s \1 | head -n 1)/" file.txt
This doesn't work, since \1 is not set. However, the shell is getting called. Can I somehow push the sed match variables to that subprocess?
The accept answer is just plain wrong. Proof:
Make an executable script foo.sh:
#! /bin/bash
echo $* 1>&2
Now run it:
$ echo foo | sed -e "s/\\(foo\\)/$(./foo.sh \\1)/"
\1
$
The $(...) is expanded before sed is run.
So you are trying to call an external command from inside the replacement pattern of a sed substitution. I dont' think it can be done, the $... inside a pattern just allows you to use an already existent (constant) shell variable.
I'd go with Perl, see the /e option in the search-replace operator (s/.../.../e).
UPDATE: I was wrong, sed plays nicely with the shell, and it allows you do to that. But, then, the backlash in \1 should be escaped. Try instead:
sed "s/^URL=\(.*\)/TITLE=$(curl -s \\1 | head -n 1)/" file.txt
Try this:
sed "s/^URL=\(.*\)/\1/" file.txt | while read url; do sed "s#URL=\($url\)#TITLE=$(curl -s $url | head -n 1)#" file.txt; done
If there are duplicate URLs in the original file, then there will be n^2 of them in the output. The # as a delimiter depends on the URLs not including that character.
Late reply, but making sure people don't get thrown off by the answers here -- this can be done in gnu sed using the e command. The following, for example, decrements a number at the beginning of a line:
echo "444 foo" | sed "s/\([0-9]*\)\(.*\)/expr \1 - 1 | tr -d '\n'; echo \"\2\";/e"
will produce:
443 foo