我想交换两行,但前提是它们的顺序错误。例如,如果我有XML行(文件中的任何位置,在某些位置不需要),如下所示:
<person>
<given-name>John</given-name>
<surname>Smith</surname>
</person>
我想交换第二行和第三行,以便生成
<person>
<surname>Smith</surname>
<given-name>John</given-name>
</person>
但仅限于那些行无序的文件。有没有办法用sed或其他linux工具做到这一点?
答案 0 :(得分:1)
这可能适合你(GNU sed);
sed -r '$!N;s/^(\s*<given-name>.*)\n(\s*<surname>.*)/\2\n\1/;P;D' file
一次读取2行,如果组合错误则交换行。
答案 1 :(得分:0)
假设&#34;第4行&#34;和&#34;第3行&#34;是模式而不是整行:
awk -v first="line 4" -v second="line 3" '
$0 ~ second { seen_second = 1 }
$0 ~ first && ! seen_second {
this_line = $0
# assume the second line is the *next* line
getline
print
print this_line
next
}
1
' file
这不会修改文件。要做到这一点:
awk '...' file > tempfile &&
mv file file.bak &&
mv tempfile file
答案 2 :(得分:0)
如果您希望surname
之前来given-name
并拥有此数据:
cat file
<person>
<given-name>John</given-name>
<surname>Smith</surname>
</person>
<person>
<surname>Hanson</surname>
<given-name>Thor</given-name>
</person>
如果错误,则awk
会更改surname
和given-name
的顺序:
awk '/<person>/ {f=NR} f && f+1==NR && /<given-name>/ {a=$0;getline;print $0 RS a;next} 1' file
<person>
<surname>Smith</surname>
<given-name>John</given-name>
</person>
<person>
<surname>Hanson</surname>
<given-name>Thor</given-name>
</person>
工作原理:
awk '
/<person>/ { # if line include <person> do:
f=NR} # do set flag "f" to line record
f && f+1==NR && /<given-name>/ { # if flag "f" is true and flag "f+1" equal "NR" and line include <given-name> do:
a=$0 # set "a" to current line
getline # get next line
print $0 RS a # print current line and previous line
next} # skip to next record
1 # print all other lines
' file # read the file