0

我有以下形式的数据:

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

现在我想将此数据转换为以下形式:

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

我知道我可以使用 C++ 来做到这一点,但是有没有办法使用 linux 来做到这一点。我知道 sed 擅长替换字符......但我不知道应该如何使用 sed 来替换上述形式。

4

5 回答 5

2
sed "N;s/\(.*\)\n\(.*\) \.$/\2 \1./" YourFile

sed 默认一次读取 1 行到工作缓冲区,并在进程结束时打印内容,从下一行开始处理。

N : 添加一个 \n 到缓冲区而不是加载下一行输入

s/Part1/Part2/: 从缓冲区开始直到 \n,\n 比一切都直到 . 在 end($) 之前并以不同的顺序重写它 \1 \2 分别是第一组和第二组的内容(一组是在 s/Part1/Part2/ 的第一部分中 ( 和 ) 之间找到的匹配元素的内容)

请注意,这里使用 \ 主要用于转义下一个字符,因为 " " 和 . 意思是“点”

于 2013-11-06T12:56:31.983 回答
2

这个单线适用于您的示例:

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

解释:

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
于 2013-11-06T12:53:02.333 回答
0

通过使用 重新定义记录分隔符gawk

$ awk 'NR>1{print $1,$2,R $3}{R=RT}' RS='<some text[^>]>' file
<text1> <text2> <some text0>.
<text3> <text4> <some text1>.
于 2013-11-06T12:59:32.373 回答
0

我会使用 awk,但这里有一个很长的对比管道

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>.
于 2013-11-06T13:00:09.630 回答
0

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 a b Print this line, previous line and b (the .)

于 2013-11-06T13:23:16.177 回答