Search for a pattern and replace it in shell script - shell

Hello I have a file with multiple lines. I need to search for a pattern ("") and replace it with another one (/"") with condition that its suffix with any string.
Ex:
cat myfile
27;"";"firstName"";"lastName";"user1";6;"Change!1"
28;"aaa#g.com";"Pravej0001";"Khan001";"test_u_001";7;"Change!1"
I need to replace firstName"" with firstName/"" in line number one.
I have already tried below code in sed :
sed 's/[A-Za-z0-9]""/\/""/g' myfile
but it is giving output as
27;"";"firstNam/"";"lastName";"user1";6;"Change!1"
28;"aaa#g.com";"Pravej0001";"Khan001";"test_u_001";7;"Change!1"
where e is replaced with / . I dont want to disturb the firstName.
Expected output should be like this:
27;"";"firstName/"";"lastName";"user1";6;"Change!1"
28;"aaa#g.com";"Pravej0001";"Khan001";"test_u_001";7;"Change!1"
Any help in sed/awk/shell will work.

sed 's/\([A-Za-z0-9]\)""/\1\/""/g' myfile
or more robustly across locales:
sed 's/\([[:alnum:]]\)""/\1\/""/g' myfile

Related

Remove word from a line - Bash

I want to remove the & from all the line
?daypartId=1&catId=1
?daypartId=1&catId=2
?daypartId=1&catId=11
?daypartId=1&catId=10
?daypartId=1&catId=6
?daypartId=1&catId=4
?daypartId=1&catId=14
?daypartId=1&catId=5
?daypartId=1&catId=3
?daypartId=1&catId=8
Expected output:
?daypartId=1&catId=1
?daypartId=1&catId=2
?daypartId=1&catId=11
?daypartId=1&catId=10
?daypartId=1&catId=6
?daypartId=1&catId=4
?daypartId=1&catId=14
?daypartId=1&catId=5
?daypartId=1&catId=3
?daypartId=1&catId=8
removing & from the input is what i need. I am stuck at this problem please help.
You could do simply with sed like below:
sed 's/amp;//' myfile.txt
This would search for amp; and replace it with an empty string in a file called myfile.txt
If you want to replace it within the file, then you could use -i option as below:
sed -i 's/amp;//' myfile.txt
If you have multiple such occurrences in a line, you could use a global replacement as below:
sed 's/amp;//g' myfile.txt

Remove/replace a dynamic String in file using unix

I have File containing the data like below
File Name :- Test.txt
TimeStamp_2017-12-43 09:09:14.0999/-ext-10100/Year/Month/Day
TimeStamp_2000-12-43 07:09:14.0999/-ext-10200/Year/Month/Day
TimeStamp_2015-12-43 06:09:14.0999/-ext-10200/Year/Month/Day
TimeStamp_2010-12-43 05:09:14.0999/-ext-10200/Year/Month/Day
TimeStamp_2011-12-43 04:09:14.0999/-ext-1090/Year/Month/Day
TimeStamp_2018-12-43 03:09:14.0999/-ext-920/Year/Month/Day
TimeStamp_2013-12-43 02:09:14.0999/-ext-1200/Year/Month/Day
TimeStamp_2016-12-43 01:09:14.0999/-ext-02/Year/Month/Day
Here i need to replace or remove below format in each line
TimeStamp_*/-ext-*
**Input line in file(Sampel TimeStamp value and -ext- value is changing every time)
TimeStamp_2017-12-43 09:09:14.0999/-ext-10100/Year/Month/Day
Ouput Line after remove or replace
Year/Month/Day
Can any one help on this Question
Simply with **sed**:
sed 's#.*-ext-[^/]*/##' file
Use below sed command, it will work for you. How will it work? First it will find the pattern TimeStamp_.*-ext-.* (here you need to add dot . with * to inform sed command that you are using * as wild card character) and replace with a blank line and second expression /^\s*$/d will search for blank line and remove it and finally you will get your required output. Every expression is separated with ; in sed command.
sed -e 's/TimeStamp_.*-ext-.*//;/^\s*$/d' Test.txt > tmp.txt
mv tmp.txt Test.txt
Hope this will help you.
When you wat to keep everything after the second slash, use
cut -d"/" -f3- Test.txt

Change specific part of a line in a file with sed

I have a line in a autoexec.py file that I want another script to be able to modify:
kodi.executebuiltin("PlayMedia(/path/to/file)")
I was thinking of using sed to override the value within PlayMedia() depending on certain conditions.
Can sed be used to only touch and overwrite the parts between the PlayMedia() brackets and nothing else? Or is further processing/regex needed?
You could use sed. The below code will replace the chars present inside the brackets following PlayMedia string with foo.
sed 's/\b\(PlayMedia\)([^)]*)/\1(foo)/g' file
If the string you want to replace is a path, you must use a different sed delimiter because filepath may contain forward slashes.
sed 's~\b\(PlayMedia\)([^)]*)~\1(foo)~g' file
Example:
$ echo 'kodi.executebuiltin("PlayMedia(/path/to/file)")' | sed 's/\b\(PlayMedia\)([^)]*)/\1(foo)/g'
kodi.executebuiltin("PlayMedia(foo)")

Using sed to replace the first instance of an entire line beginning with string

I am attempting to write a bash script that will use sed to replace an entire line in a text file beginning with a given string, and I only want it to perform this replacement for the first match.
For example, in my text file I may have:
hair=brown
age=25
eyes=blue
age=35
weight=177
And I may want to simply replace the first occurrence of a line beginning with "age" with a different number without affecting the 2nd instance of age:
hair=brown
age=55
eyes=blue
age=35
weight=177
So far, I've come up with
sed -i "0,/^PATTERN/s/^PATTERN/PATTERN=XY/" test.txt
but this will only replace the string "age" itself rather than the entire line. I've been trying to throw a "\c" in there somewhere to change the entire line but nothing is working so far. Does anyone have any ideas as to how this can be resolved? Thanks.
Like #ruakh suggests, you can use
sed -i "0,/^PATTERN/ s/^PATTERN=.*$/PATTERN=XY/" test.txt
A shorter and less repetitive way of doing the same would be
sed -i '0,/^\(PATTERN=\).*/s//\1XY/' test.txt
which takes advantage of backreferences and the fact that not specifying a pattern in an s-expression will use the previously matched pattern.
0,...-ranges only work in GNU sed. An alternative might be to use shell redirect with sed:
{ sed '/^\(PATTERN\).*/!n; s//\1VAL;q'; cat ;} < file
or use awk:
awk '$1=="LABEL" && !n++ {$2="VALUE"}1' FS=\\= OFS=\\= file

How to apply two different sed commands on a line?

Q1:
I would like to edit a file containing a set of email ids such that all the domain names become generic.
Example,
peter#yahoo.com
peter#hotmail.co.in
philip#gmail.com
to
peter_yahoo#generic.com
peter_hotmail#generic.com
philip_gmail#generic.com
I used the following sed cmd to replace # with _
sed 's/#/_/' <filename>
Is there a way to append another sed cmd to the cmd mentioned above such that I can replace the last part of the domain names with #generic.com?
Q2:
so how do I approach this if I had text at the end of my domain names?
Example,
peter#yahoo.com,i am peter
peter#hotmail.co.in,i am also peter
To,
peter_yahoo.com#generic.com,i am peter
peter_hotmail.co.in#generic.com,i am also peter
I tried #(,) instead of #(.*)
it doesn't work and I cant think of any other solution
Q3:
Suppose if my example is like this,
peter#yahoo.com
peter#hotmail.co.in,i am peter
I want my result to be as follows,
peter_yahoo.com#generic.com
peter_hotmail.co.in#generic.com,i am peter,i am peter
How do i do this with a single sed cmd?
The following cmd would result in,
sed -r 's!#(.*)!_\1#generic.com!' FILE
peter_yahoo.com#generic.com
peter_hotmail.co.in,i am peter,i am peter#generic.com
And the following cmd wont work on "peter#yahoo.com",
sed -r 's!#(.*)(,.*)!_\1#generic.com!' FILE
Thanks!!
Golfing =)
$ cat FILE
Example,
peter#yahoo.com
peter#hotmail.co.in
philip#gmail.com
$ sed -r 's!#(.*)!_\1#generic.com!' FILE
Example,
peter_yahoo.com#generic.com
peter_hotmail.co.in#generic.com
philip_gmail.com#generic.com
In reply to user1428900, this is some explanations :
sed -r # sed in extended regex mode
s # substitution
! # my delimiter, pick up anything you want instead !part of regex
#(.*) # a literal "#" + capture of the rest of the line
! # middle delimiter
_\1#generic.com # an "_" + the captured group N°1 + "#generic.com"
! # end delimiter
FILE # file-name
Extended mode isn't really needed there, consider the same following snippet in BRE (basic regex) mode :
sed 's!#\(.*\)!_\1#generic.com!' FILE
Edit to fit your new needs :
$ cat FILE
Example,
peter#yahoo.com,I am peter
peter#hotmail.co.in
philip#gmail.com
$ sed -r 's!#(.*),.*!_\1#generic.com!' FILE
Example,
peter_yahoo.com#generic.com
peter#hotmail.co.in
philip#gmail.com
If you want only email lines, you can do something like that :
sed -r '/#/s!#(.*),.*!_\1#generic.com!' FILE
the /#/ part means to only works on the lines containing the character #
Edit2:
if you want to keep the end lines like your new comments said :
sed -r 's!#(.*)(,.*)!_\1#generic.com\2!' FILE
You can run multiple commands with:
sed -e cmd -e cmd
or
sed -e cmd;cmd
So, in your case you could do:
sed -e 's/#/_/' -e 's/_.*/_generic.com/' filename
but it seems easier to just do
sed 's/#.*/_generic.com/' filename
sed 's/\(.*\)#\(.*\)\..*/\1_\2#generic.com/'
Expression with escaped parentheses \(.*\) is used to remember portions of the regular expression. The "\1" is the first remembered pattern, and the "\2" is the second remembered pattern.
The expression \(.*\) before the # is used to remember beginning of the email id (peter, peter, philip).
The expression \(.*\)\. after the # is used to remember ending of the email id (yahoo, hotmail, gmail). In other words, it says: take something between # and .
The expression .* at the end is used to match all trailing symbols in the e-mail id (.com, .co.in, .co.in).

Resources