简体   繁体   中英

specific string replacements using linux commands

I have data in the following form:

<some text0>
<text1> <text2> .
<some text1>
<text3> <text4> .

Now I want to convert this data into the following form:

<text1> <text2> <some text0>.
<text3> <text4> <some text1>.

I know I can do it using C++, but is there some way of doing this using linux. I know sed is good at replacing characters...but I am not getting as to how should I use sed to do replacements of the above form.

this one-liner works for your example:

kent$  awk '!/\.$/{s=$0;next}sub(/\.$/,s".")' f
<text1> <text2> <some text0>.
<text3> <text4> <some text1>.

explanation:

awk               #the program
!/\.$/{s=$0;next} #if the line was not ending with dot(.),
                  #assign it to s, read next line
sub(/\.$/,s".")   #we are here when the line ends with ".",
                  #then we replace ending "." with s, and print.
f                 #the input file
sed "N;s/\(.*\)\n\(.*\) \.$/\2 \1./" YourFile

sed read 1 line at a time by default into a working buffer and print the content at end of process starting next line to process.

N : add a \\n to the buffer than load the next line of input

s/Part1/Part2/ : take begining of the buffer until \\n, the \\n than everything until the . before the end($) and rewrite it in different order \\1 \\2 are respectively content of 1st and second group (a group is the content found matching element between ( and ) in first part of s/Part1/Part2/)

note that \\ is used here mainly for escaping next char due to shell substitution between " " and . mean "dot"

By redefining the record seperator with gawk :

$ awk 'NR>1{print $1,$2,R $3}{R=RT}' RS='<some text[^>]>' file
<text1> <text2> <some text0>.
<text3> <text4> <some text1>.

I would use awk, but here's a long pipeline for contrast

sed 's/\.$//' <<END | tac | paste -d " " - - | tac | sed 's/$/./'
<some text0>
<text1> <text2> .
<some text1>
<text3> <text4> .
END    sed 's/\.$//' <<END | tac | paste -d " " - - | tac | sed 's/$/./'
<some text0>
<text1> <text2> .
<some text1>
<text3> <text4> .
END
<text1> <text2>  <some text0>.
<text3> <text4>  <some text1>.

Simple and understandable awk

awk '{a=$0;getline;b=$NF;$NF="";print $0 a b}'
<text1> <text2> <some text0>.
<text3> <text4> <some text1>.

a=$0 Store first line in variable a
getline Get the next line b=$NF Store the last field in b (the . ) $NF="" Clear the last field print $0 ab Print this line, previous line and b (the . )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM