Replace substring with sed - shell

I have a string like this :
test:blabla
And with sed, I want to replace what's after the ':' with something else.
I can manage to replace a word, but not the one after the ':'. I searched on the internet for the answer, but I didn't found anything.
Any help ?

Use: sed 's/:.*/:replaceword/'
$ echo test:blabla | sed 's/:.*/:replaceword/'
test:replaceword
Or for the situation test test:blabla test where you only want to replace the word following : use sed 's/:[^ ]*/:replaceword/':
$ echo "test test:blabla test" | sed 's/:[^ ]*/:replaceword/'
test test:replaceword test
# Use the g flag for multiple matches on a line
$ echo "test test:blabla test test:blah2" | sed 's/:[^ ]*/:replaceword/g'
test test:replaceword test test:replaceword

> echo $SER2
test:blabla
> echo $SER2 | sed 's/\([^:]*:\).*/\1replace/g'
test:replace
>

Related

How to use grep to extract a text between two patterns

I am working with bash script.
There is a file and inside the file, it is like this:
Hello /hi/12349/Jane?
Hello /hi/123?=Jane/
Hello /hey/123450/Jane
Hello /hi/123/Jane
And I want to extract any digits between "Hello /hi/" and "/", and between "Hello /hi/" and "/" there only should be digits.
So in this case the result I want is:
12349
123
I have tried this:
cat file.txt | grep -o -P '(?>=Hello \/hi\/).*(?=\/)'
But what I have tried printed out everything after "Hello /hi" :(
You can use sed for that:
sed -nE 's|^Hello /hi/([0-9][0-9]*)/.*|\1|p' file
12349
123
With GNU grep:
grep -Po '(?<=^Hello /hi/)[0-9]+(?=/)' file.txt
Output:
12349
123
Extracting things seems like a case to use a Stream EDitor.
sed -n '/Hello \/hi\/\([0-9]*\)\.*//s//\1/p' file.txt
Another possibility is an extended regex ( -E )...
grep -o -E "[^][a-zA-Z /?=]{1,8}" grep.txt
...that use a pattern of unwanted chars and [^] means in this case: not
puts out...
12349
123
123450
123

Using sed to replace some lower case letters to upper case

I'm trying to replace _[lowercase] to [uppercase] using sed in bash.
So far I've tried this code:
new_arr=$( echo $old_arr | sed -e 's%_\(.\)%\1\U%g' )
With input of
this_is_a_function()
i expected the output to be
thisIsAFunction()
but i got
thisisafunction
Do you have a suggestion for what I might be doing wrong?
Could you please try following.
sed 's/_\([a-z]\)/\U\1/g' Input_file
So in OP's case it should be something like:
new_arr=$( echo "$old_arr" | sed 's%_\([a-z]\)%\U\1%g' )

Bash: replace 4 occourance of a string if exist

I have a string that is sometimes
xxx.11_222_33_44_555.yyy
and sometimes
xxx.11_222_33_44.yyy
I would like to:
Check if has 4 occourances of _ (figured out how to do it).
If so - remove string's _33 (the 33 string changes, can be any number), so I am left with xxx.11_222_44.yyy.
Using sed :
sed 's/\(_[0-9]*\)_[0-9]*\(_[0-9]*_[0-9]*\)/\1\2/'
It matches the four underscores and replace the whole by the needed parts.
Test run :
$ echo "xxx.11_222_33_44_555.yyy" | sed 's/\(_[0-9]*\)_[0-9]*\(_[0-9]*_[0-9]*\)/\1\2/'
xxx.11_222_44_555.yyy
$ echo "xxx.11_222_33_44.yyy" | sed 's/\(_[0-9]*\)_[0-9]*\(_[0-9]*_[0-9]*\)/\1\2/'
xxx.11_222_33_44.yyy
perhaps something like this
echo "xxx.11_222_33_44.yyy" | sed -e's/\.\([0-9]\+\)_\([0-9]\+\)_\([0-9]\+\)_\([0-9]\+\)\./.\1_\2_\4./'
which checks if there are 4 groups of numbers separated by _ between the two dots and if yes, it leaves out the third group
try this;
echo "xxx.11_222_33_44_555.yyy" | awk -F'_' 'NF>4{print $1"_"$2"_"$4"_"$5};'
Solution using perl and Lookahead and Lookbehind
$ a="xxx.11_222_33_44_555.yyy"
$ perl -pe 's/\.\d+_\d+_\K\d+_(?=\d+_\d+\.)//' <<< "$a"
xxx.11_222_44_555.yyy

How to get delete word combination "Name Server:" without quotes but keep 'Name Server:someletters/digits' in sed

I have the following lines:
Name Server:NS92.WORLDNIC.COM(or some other value)
Name Server:
Name Server:
Name Server:
Please see the screenshot for better understanding: http://imgur.com/q6Ir4lo
How do I get rid of the 'Name Server:' line but keep the line with the value?
I tried /Name Server:{0,0}/d but it deletes all lines.
Thanks
I was able to get the following two lines to work:
I believe the [:space:] is POSIX compliant:
cat test |sed '/^Name Server:[[:space:] \t]\?$/d'
An alternative is simply:
cat test |sed '/^Name Server:[ \t]\?$/d'
I've also found in sed, that most of the meta-characters (eg + ? ) need to be escaped for sed to recognize them correctly.
This works for me:
echo "Name Server:NS92.WORLDNIC.COM" | sed 's/^Name Server://'
cut -d ":" -f 2 < ff | sed '/^$/d'
Uses ':' as delimiter and splits the line (-d option), then selects the second field (-f option)

Pipes inside of sed

Is there a way to send the back references of the SED s/// command to pipes? In order to get an entry from the text, change it, and then write it back. I found that a substitution inside of SED works:
$ echo 'Test ....' | sed 's/Test/'$( echo "<\0>" )'/'
<Test> ....
But the first pipe does not:
$ echo 'Test ....' | sed 's/Test/'$( echo "<\0>" | tr 's' 'x' )'/'
<Test> ....
What is the reason? Additionally, I can't understand why this works at all. I thought that $() substitution should be processed before sed (all the more as I broke the quotes).
And how can I insert one s/// command into another using sed? I use bash.
The tr command is operating on the text "<\0>", not on "<Test>". The back reference isn't expanded in sed until after the pipeline completes. Your second example is equivalent to
foo=$( echo "<\0>" | tr 's' 'x' )
echo 'Test ....' | sed 's/Test/'$foo'/'
It's a little easier to see here that tr has no way of seeing "Test" in its input.
You can achieve the effect you're after with GNU sed and the e flag:
echo 'Test ....' | sed 's/Test.*/echo "<\0>" | tr s x/e'
Output:
<Text ....>

Resources