how to remove an entire line in with a pattern using sed - sed

i have a file :
hi:: hello hai
welcome
bye
I want to remove the lines with the word hi
I tried the following command:
sed -i -e "/hi/d" filename
but the output was
:: heloo hai
How can I remove the entire line using sed?? That is the line "hi::hello hai"

Try /^.*hi.*$/d can.t test right now so it is a wild guess

This should be sufficient:
sed -e '/hi/d' file
Tested and works.
tom#eee ~ % cat test
hi:: hello hai
welcome
bye
tom#eee ~ % sed -e '/hi/d' test
welcome
bye
Also as damienfrancois stated grep works too:
tom#eee ~ % grep -v 'hi' test
welcome
bye

Using awk you can do this
awk '!/^hi/' file
welcome
bye
This will remove lines with hi in start of line. You does not say if the world can be in middle of the sentence. If so, do:
awk '!/hi/'
welcome
bye

Related

Replace last text ocurrence in a file with sed

I'm tying to replace the last occurrence of a word in a file.
hello
bye
bye
bye
hello
I am able to replace it by indicating the line number.
sed -i '4 s/bye/adieu' file
Also, if the occurrence is in the last line.
sed -i '$ s/hello/salut' file
But, how can I find and replace the last bye without indicating the line number?
This is a bit gross and probably not recommended for large files, but it should work:
sed -zE '$ s/(.*)bye/\1adieu/' file
where -z makes Sed consider the whole file as a single line with \n interspersed, and -E is to use () instead of \(\).
If there's a chance that a line contains bye but is not just bye, as in goodbye/good bye/whatever, than you can go with
sed -zE '$ s/(.*)(^|\n)bye($|\n)/\1adieu/' file
One possible solution using tac | gnu-sed | sed:
tac file | sed '0,/^bye$/ s//adieu/' | tac
hello
bye
bye
adieu
hello
Details:
tac prints file in reverse
0,/^bye$/ matches a line from beginning to first occurrence of bye line
s//adieu/ substitutes that line with adieu
tac prints file in reverse again to get original order
Alternatively this awk solution would work in any version of awk:
awk 'FNR == NR {if ($0 == "bye") last = FNR; next}
FNR == last {$0 = "adieu"} 1' file file
hello
bye
bye
adieu
hello

Parse file and insert new line after each occurrence

On a Unix system I am trying to add a new line in a file using sed or perl but it seems I am missing something.
Supposing my file has multiple lines of texts, always ending like this {TNG:}}${1:F01.
I am trying to find a to way to add a new line after the }$, in this way {1 should always start on a new line.
I tried it by escaping $ sign using this:
perl -e '$/ = "\${"; while (<>) { s/\$}\{$/}\n{/; print; }' but it does not work.
Any ideas will be appreciated.
give this a try:
sed 's/{TNG:}}\$/&\n/' file > newfile
The sed will by default use BRE, that is, the {}s are literal characters. But we must escape the $.
kent$ cat f
{TNG:}}${1:F01.
kent$ sed 's/{TNG:}}\$/&\n/' f
{TNG:}}$
{1:F01.
With perl:
$ cat input.txt
line 1 {TNG:}}${1:F01
line 2 {TNG:}}${1:F01
$ perl -pe 's/TNG:\}\}\$\K/\n/' input.txt
line 1 {TNG:}}$
{1:F01
line 2 {TNG:}}$
{1:F01
(Read up on the -p and -n options in perlrun and use them instead of trying to do what they do in a one-liner yourself)

sed - insert lines when text found / not found

I have issue with sed, i need to accomplish two things with a csv file
in front of each line that does not start UNES I need to add tag "BF2;"
at the start of the file (after UNES if present) I need to add a tag "UNH;"
Example (no UNES;)
50000024;IE15;041111;113901;verstuurd;Aangift;
50000024;IE15;041111;113901;verstuurd;Aangifte;
50000024;IE15;041111;113901;verstuurd;Aangifte;
Example (with UNES;)
UNES;
50000024;IE15;041111;113901;verstuurd;Aangift;
50000024;IE15;041111;113901;verstuurd;Aangifte;
50000024;IE15;041111;113901;verstuurd;Aangifte;
so far I have this:
sed -e 's/^\([^"UNES"]\)/BF2;\1/' | sed '/UNES/ a\UNH;'
THis works as long as a UNES; tag is present - I can't seem to figure out how to insert the UNH; when UNES is not present!
Any help much appreciated
Sample output:
UNES;
UNH;
BF2;50000024;IE15;041111;113901;verstuurd;Aangifte;
BF2;50000024;IE15;041111;113901;verstuurd;Aangifte;
BF2;50000024;IE15;041111;113901;verstuurd;Aangifte;
Here's how you could do it using awk:
awk 'NR==1 {if(f=/^UNES;/)print; print "UNH;"} !f{print "BF2;" $0} {f=0}' file
On the first line, if /^UNES;/ is matched, print it and set the flag f. Always print "UNH;". If the f flag has been set, don't do the next action, which works for the rest of the lines. Always reset f to 0 after the first line so all further lines have "BF2;" added to the start.
Testing it out:
$ cat file
UNES;
50000024;IE15;041111;113901;verstuurd;Aangift;
50000024;IE15;041111;113901;verstuurd;Aangifte;
50000024;IE15;041111;113901;verstuurd;Aangifte;
$ awk 'NR==1 {if(f=/^UNES;/)print; print "UNH;"} !f{print "BF2;" $0} {f=0}' file
UNES;
UNH;
BF2;50000024;IE15;041111;113901;verstuurd;Aangift;
BF2;50000024;IE15;041111;113901;verstuurd;Aangifte;
BF2;50000024;IE15;041111;113901;verstuurd;Aangifte;
$ cat file2
50000024;IE15;041111;113901;verstuurd;Aangift;
50000024;IE15;041111;113901;verstuurd;Aangifte;
50000024;IE15;041111;113901;verstuurd;Aangifte;
$ awk 'NR==1 {if(f=/^UNES;/)print; print "UNH;"} !f{print "BF2;" $0} {f=0}' file2
UNH;
BF2;50000024;IE15;041111;113901;verstuurd;Aangift;
BF2;50000024;IE15;041111;113901;verstuurd;Aangifte;
BF2;50000024;IE15;041111;113901;verstuurd;Aangifte;
You can use this sed command:
sed '/^UNES;$/{i\
UNH;
n};s/^/BF2;/;' file.txt
details:
/^UNES;$/i\
UNH; insert a new line when UNES; is the whole line.
n replaces the pattern space with the next line
Try this, its works for me
sed '/^UNES;$/{i\
UNH;
n};s/^[0-9]*/BF2;&/;'

search string and excise beginning portion - Solaris

Another Solaris question.
This is my file.
/abc/123/gfh/hello/what/is/up <THIS WOULD BE WHERE A NEW LINE STARTS>
bhn/fda/fds/hello/the/sky/is/blue <THIS WOULD BE WHERE A NEW LINE STARTS>
...etc
I need to delete everything before "hello" include the forward slash "/" infront of it for everyline in the file...
I'm stuck -> I had used a sed -E command but Solaris doesn't recognize the "-E". sigh
I think you can grep this:
grep -o hello.*
This should delete everything up to the slash before "hello":
sed -e 's|^.*hello/|hello|' <inputfile >outputfile
That should do it:
sed -e 's/.hello(.)/hello\1/'
#user4815162342: No need for "^" in the sed solution, ".*" would suffice.
Since there was an awk tag too, here's the equivalent awk solution:
awk '{sub(/.*hello\//,"hello")}1'

To remove blank lines in data set

I need a one liner using sed, awk or perl to remove blank lines from my data file. The data in my file looks like this -
Aamir
Ravi
Arun
Rampaul
Pankaj
Amit
Bianca
These blanks are at random and appear anywhere in my data file. Can someone suggest a one-liner to remove these blank lines from my dataset.
it can be done in many ways.
e.g with awk:
awk '$0' yourFile
or sed:
sed '/^$/d' yourFile
or grep:
grep -v '^$' yourFile
A Perl solution. From the command line.
$ perl -i.bak -n -e'print if /\S/' INPUT_FILE
Edits the file in-place and creates a backup of the original file.
AWK Solution:
Here we loop through the input file to check if they have any field set. NF is AWK's in-built variable that is set to th number of fields. If the line is empty then NF is not set. In this one liner we test if NF is true, i.e set to a value. If it is then we print the line, which is implicit in AWK when the pattern is true.
awk 'NF' INPUT_FILE
SED Solution:
This solution is similar to the ones mentioned as the answer. As the syntax show we are not printing any lines that are blank.
sed -n '/^$/!p' INPUT_FILE
You can do:
sed -i.bak '/^$/d' file
A Perl solution:
perl -ni.old -e 'print unless /^\s*$/' file
...which create as backup copy of the original file, suffixed with '.old'
for perl it is as easier as sed,awk, or grep.
$ cat tmp/tmpfile
Aamir
Ravi
Arun
Rampaul
Pankaj
Amit
Bianca
$ perl -i -pe 's{^\s*\n$}{}' tmp/tmpfile
$ cat tmp/tmpfile
Aamir
Ravi
Arun
Rampaul
Pankaj
Amit
Bianca