How to do line break using SED in solaris? - sed

How to use sed for the below scenario where in my prompt i don know the way to delimit \n.
In the below pattern there should be a new line whenever "no" occurs.
yesnoyesno
as
yes
noyes
no
Please help.

sed 's/search pattern/
replace pattern on a new line/option'
use a real new line (or CTRL+v+j for a one-liner entry)
\n on replace pattern is not know as new line in posix sed (but well in search pattern so a s/foo\(\n\)bar/&\1lazy dog/ will normaly work)
in this request :
sed 's/no/
&/g' YourFile

Related

How to replace all occurrences using sed

I couldn't make it work the way I want.
echo 'https://aaa/xx_one/bbb/xx_two/ccc' | sed 's|^\(https://.*\)xx_|\1OK_|g'
https://aaa/xx_one/bbb/OK_two/ccc
The output I wanted is: https://aaa/OK_one/bbb/OK_two/ccc
That is, I just want to replace every occurrences of xx_ with OK_ and with that specific constraint.
Need some help. I want it in sed. Thanks.
If the line should start with https://, which you originally didn't say, you can use an "address" in sed:
sed '\=^https://= s/xx_/OK_/g'
Original answer: (will replace xx_ by OK_ after https://, but the line doesn't have to start with it).
Perl to the rescue:
perl -pe '1 while s=https://.*\Kxx_=OK_=g'
-p reads the input line by line, prints each line after processing;
\K in a regular expression forgets what's been matched so far. In this case, it will only replace the xx_ by OK_, but it still has to match https://.* before it;
The substitution runs in a while loop until there's nothing to replace.

Substring file name in Unix using sed command

I want to substring the File name in unix using sed command.
File name : Test_Test1_Test2_10082019_030013.csv.20191008-075740
I want the characters after the 3rd underscore or (all the characters after Test2 ) i need to be printed .
Can this be done using sed command?
I have tried this command
sed 's/^.*_\([^_]*\)$/\1/' <<< 'Test_Test1_Test2_10082019_030013.csv.20191008-075740'
but this is giving result as 030013.csv.20191008-075740
I need it from 10082019_030013.csv.20191008-075740
Thanks
Neha
To remove from the beginning up to including the 3rd underscore you can use
sed 's/^\([^_]*_\)\{3\}//' <<< 'Test_Test1_Test2_10082019_030013.csv.20191008-075740'
This removes the initial part that consists of 3 groups of (any number of non-underscore characters followed by an underscore). The result is
10082019_030013.csv.20191008-075740
If you use GNU sed you can switch it to extended regular expressions and omit the backslashes.
sed -r 's/^([^_]*_){3}//' <<< 'Test_Test1_Test2_10082019_030013.csv.20191008-075740'
Could you please try following.
sed 's/\([^_]*\)_\([^_]*\)_\([^_]*\)_\(.*\)/\4/' Input_file
Or as per Bodo's nice suggestion:
sed 's/[^_]*_[^_]*_[^_]_\(.*\)/\1/' Input_file
This might work for you (GNU sed):
sed 's/_/\n/3;s/.*\n//;t;s/Test2/\n/;s/.*\n//;t;d' file
Replace the third _ by a newline and then remove everything upto and including the first newline. If this succeeds, bail out and print the result. Otherwise, try the same method with Test2 and if this fails delete the entire line.

how to find a specific character combination and add a newline

I have a large file that looks like this
(something,something1,something2),(something,something1,something2)
how do I use sed and find ),( and replace it with );( or add a newline between the parentheses that has a comma character.
I did try sed 's/),(/),\n(/g' filename.txt but for some reason it does not work
for those who come here and want to know how this work without getting a lot of stackoverflow "greetings"
since I was on Mac os x you need to replace your \n with \'$'\n''
so to find ),( and add a new line between the parentheses this is the command I used
sed 's/;/\'$'\n''/g' testdone.txt > testdone2.txt
ES
echo "(something,something1,something2),(something,something1,something2)" | sed "s|),(|);(|"
This prints the below for me.
(something,something1,something2);(something,something1,something2)
For new line
echo "(something,something1,something2),(something,something1,something2)" | sed "s|),(|)\n(|"
And the above prints the below.
(something,something1,something2)
(something,something1,something2)

sed oneliner to add a line before another line

I need to add a line with bar before each line with foo with sed.
I need to do this in a Makefile and so I cannot use i\ because it needs a newline in standard sed (not GNU sed, e.g., the one in Mac OS X) and this cannot be done in a Makefile (at least, not nicely).
The solution I found is:
sed '/foo/{h;s/.*/bar/;p;g;}' < in > out
This saves the line, replaces its contents with bar, prints the new line, restores the old line (and prints it by default).
Is there a simpler solution?
BSD sed
This will put bar before every line with foo:
sed $'/foo/{s/^/bar\\\n/;}' in >out
GNU sed
This will put bar before every line with foo:
sed '/foo/{s/^/bar\n/;}' in >out
How it works
/foo/
This selects lines that contain foo.
s/^/bar\n/
^ matches the beginning of the line. Thus, for the selected lines, this substitutes in bar\n at the beginning of the line. This effectively adds a new line to precede the one containing foo.
Under GNU, one can write \n and sed interprets it as a newline. This doesn't work under BSD sed. Hence the different version.
This might work for you (GNU sed):
sed '/foo/ibar' file
I'm not sure why you say you need a newline but just incase the inserted line needs to longer than one line you can employ bash so:
sed $'/foo/ibar\\\nbaz' file

Matching strings even if they start with white spaces in SED

I'm having issues matching strings even if they start with any number of white spaces. It's been very little time since I started using regular expressions, so I need some help
Here is an example. I have a file (file.txt) that contains two lines
#String1='Test One'
String1='Test Two'
Im trying to change the value for the second line, without affecting line 1 so I used this
sed -i "s|String1=.*$|String1='Test Three'|g"
This changes the values for both lines. How can I make sed change only the value of the second string?
Thank you
With gnu sed, you match spaces using \s, while other sed implementations usually work with the [[:space:]] character class. So, pick one of these:
sed 's/^\s*AWord/AnotherWord/'
sed 's/^[[:space:]]*AWord/AnotherWord/'
Since you're using -i, I assume GNU sed. Either way, you probably shouldn't retype your word, as that introduces the chance of a typo. I'd go with:
sed -i "s/^\(\s*String1=\).*/\1'New Value'/" file
Move the \s* outside of the parens if you don't want to preserve the leading whitespace.
There are a couple of solutions you could use to go about your problem
If you want to ignore lines that begin with a comment character such as '#' you could use something like this:
sed -i "/^\s*#/! s|String1=.*$|String1='Test Three'|g" file.txt
which will only operate on lines that do not match the regular expression /.../! that begins ^ with optional whiltespace\s* followed by an octothorp #
The other option is to include the characters before 'String' as part of the substitution. Doing it this way means you'll need to capture \(...\) the group to include it in the output with \1
sed -i "s|^\(\s*\)String1=.*$|\1String1='Test Four'|g" file.txt
With GNU sed, try:
sed -i "s|^\s*String1=.*$|String1='Test Three'|" file
or
sed -i "/^\s*String1=/s/=.*/='Test Three'/" file
Using awk you could do:
awk '/String1/ && f++ {$2="Test Three"}1' FS=\' OFS=\' file
#String1='Test One'
String1='Test Three'
It will ignore first hits of string1 since f is not true.