我有以下形式的数据:
<some text0>
<text1> <text2> .
<some text1>
<text3> <text4> .
现在我想将此数据转换为以下形式:
<text1> <text2> <some text0>.
<text3> <text4> <some text1>.
我知道我可以使用 C++ 来做到这一点,但是有没有办法使用 linux 来做到这一点。我知道 sed 擅长替换字符......但我不知道应该如何使用 sed 来替换上述形式。
sed "N;s/\(.*\)\n\(.*\) \.$/\2 \1./" YourFile
sed 默认一次读取 1 行到工作缓冲区,并在进程结束时打印内容,从下一行开始处理。
N
: 添加一个 \n 到缓冲区而不是加载下一行输入
s/Part1/Part2/
: 从缓冲区开始直到 \n,\n 比一切都直到 . 在 end($) 之前并以不同的顺序重写它 \1 \2 分别是第一组和第二组的内容(一组是在 s/Part1/Part2/ 的第一部分中 ( 和 ) 之间找到的匹配元素的内容)
请注意,这里使用 \ 主要用于转义下一个字符,因为 " " 和 . 意思是“点”
这个单线适用于您的示例:
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
通过使用 重新定义记录分隔符gawk
:
$ awk 'NR>1{print $1,$2,R $3}{R=RT}' RS='<some text[^>]>' file
<text1> <text2> <some text0>.
<text3> <text4> <some text1>.
我会使用 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>.
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 .
)