sed Remove everything above last match found - linux

I have a file: users.txt that looks like the below:
Name
Jack
Name
Jackson
Name
Peter
I need to remove EVERYTHING ABOVE the last match found Name so that the file looks like:
Name
Peter
I have tried searching the net, but only find awk command's that can achieve this.
I need it to be sed in order to use the -i option to save. I have come across where a file is sometimes empty when redirecting > standard output using awk.
Your time and assistance is greatly appreciated.

You can use tac twice with awk:
tac file | awk '{print} /Name/{exit}' | tac
Name
Peter

Through sed,
tac file | sed -n '0,/Name/p' | tac

Using sed without tac:
sed -n '/Name/h; //!H; ${g;p}' file
When Name is seen, replace the hold space with the current line
When Name is NOT seen, append the current line to the hold space
At the last line, replace the pattern space with the hold space and print.
Since we don't have sed in a pipeline, you can use -i to replace the file.

All in awk
awk 'x{x=x"\n"$0}/Name/{x=$0}END{print x}' file

This might work for you (GNU sed):
sed 'H;/Name/h;$!d;x' file
Hold matches in the hold space and at the end of file print the hold space with the last match.

Related

Print between special characters with sed,grep

I need to print the string between these characters....
atob(' ')
I am using a = in the second part as an attempt to stop the code on an equal signs (which the base64 string I'm trying to get ends in.)
I use this script, but it prints the entire line containing the above characters. I need just the data in between.
sed -n '/atob/,${p;/==/q;}'
I appreciate any help. Thank you.
Does this work (tested for GNU sed 4.2.2)?
 sed -n -e "s/atop('\(.*\)')/\1/p" b.txt
where b.txt is
atop('safdasdfasf')
or you can try awk
awk -F\' '/atop/ {print $2}' b.txt
(tested for gnu awk 4.0.2 and added the suggestion by Jotne)
And another working sed:
echo "atop('safdasdfasf')" | sed -r "/atop/ s/^[^']+'([^']+)'.*/\1/"
safdasdfasf

With Bash, how to print the whole lines of a .txt file which contain, in their first section, a specific string?

So far, I used grep for these kind of questions, but here, I think it can't be use. Indeed, I want a match in the first section of each line, and then print the whole line.
I wrote something like that:
cat file.txt | cut -d " " -f1 | grep root
But of course, this command does not print the whole line, but only the first section of each line that contains "root". I've heard of awk command, but even with the manual, I do not understand how to reach my goal.
Thank you in advance for your answer
Simple awk should do it:
awk '$1 ~ /root/' file.txt

Linux - Split textfile along new line

I have a testfile similar to this one:
Bla: Blubb
Bla: blubb
Relevant stuff
So basically header information followed by a newline. I need everything after the newline as the number of header-lines varies.
Does anybody have an idea on how to achieve that?
Cheers and thank you
Fabian
With sed
sed -n '/^$/,$p' file
With awk (including the newline):
awk '/^$/{p=1};p' file
With awk (excluding the newline):
awk 'p;/^$/{p=1}' file
This might work for you (GNU sed):
sed '1,/^\s*$/d' file

SED: Displaying the first 10 lines of sophisticated expression

How to use sed to find lines with the word linux? As later display a first line 10 with the word linux?
EX.:
cat file | sed -e '/linux/!d' -e '10!d' ### I can not display the first 10 lines of the word linux
cat file | sed '/linux/!d' | sed '10!d' ### It is well
How to make it work with one sed?
cat file | sed -e '/linux/!d; ...?; 10!d'
...? - storing of the buffer linux? 10 later cut the lines?
Someone explain to me?
I would use awk:
awk '/linux/ && c<10 {print;c++} c==10 {exit}' file
This might work for you (GNU sed):
sed -nr '/linux/{p;G;/(.*\n){10}/q;h}' file
Print the line if it contains the required string. If the required number of lines has already been printed quit, otherwise store the line and previous lines in the hold space.
You could use perl:
perl -ne 'if (/linux/) {print; ++$a;}; last if $a==10' inputfile
Using GNU sed:
sed -rn "/linux/{p;x;s/^/P/;ta;:a;s/^P{10}$//;x;Tb;Q;:b}" filename
Thanks. You are great. All of the examples look very nice. Wooow :) It is a pity that I can not do that.
I have not seen for 'r' option in sed. I need to learn.
echo -e 'windows\nlinux\nwindows\nlinux\nlinux\nwindows' | sed -nr '/linux/{p;G;/(.*\n){2}/q;h}'
It works very well.
echo -e 'windows\nlinux\nwindows\nlinux\nlinux\nwindows' | sed -nr '/linux/{p;G;/(.*\n){2}/q;h}' | sed '2s/linux/debian/'
Can I ask you one more example? How to get a result at one sed?

awk to print some parameters of a line

I have lines in a file in linux, and i am trying print the line without the | and without some parameters
$cat file
2013-07-15,Provider 1.99,3|30000055|2347|0,12222,1,3,0,0,0,19,aaa,bbb
2013-07-15,Provider 1.99,3|30000055|2347|0,12222,44,12,0,0,0,33,aaa,bbb
and i need the output like:
2013-07-15,Provider,2347,12222,1,3,0,0,0,19,aaa,bbb
2013-07-15,Provider,2347,12222,44,12,0,0,0,33,aaa,bbb
and i am trying with awk, but i have some problems.
If your lines have similar pattern you would to retain then you can do:
awk 'BEGIN{FS=OFS=","}{$2="Provider";$3=2347}1' file
If you don't know what the patterns are then here is a more generic one:
awk 'BEGIN{FS=OFS=","}{split($2,a,/ /);split($3,b,/\|/);$2=a[1];$3=b[3]}1' file
If it doesn't solve your problem, I am pretty sure it would help you guide to get one.
Using sed:
sed 's/ [^|]*|[^|]*|\([^|]*\)|[^,]/,\1/' input
and some shorter version:
sed 's/ .*|\([^|]*\)|[^,]*/,\1/' input
and even shorter:
sed 's/ .*|\(.*\)|[^,]*/,\1/' input
Use awk, and let blank or comma or pipe be the field separators:
awk -F '[[:blank:],|]' -v OFS=, '{
print $1,$2,$6,$8,$9,$10,$11,$12,$13,$14,$15,$16
}' file
2013-07-15,Provider,2347,12222,1,3,0,0,0,19,aaa,bbb
2013-07-15,Provider,2347,12222,44,12,0,0,0,33,aaa,bbb

Resources