如何将一些行移动到文件的顶部?

时间:2015-03-04 09:56:47

标签: linux shell awk sed ash

我有一个这样的文件:

aaa.bbb.1.ccc
xxx.bbb.21
mmm.ppp
xxx.eee
mmm.qqqq
xxx.hhh.12.ddd

我想通过一个简单的命令(使用xxx.sedawk ...)移动文件顶部以grep开头的所有行

所以我的新文件将如下所示:

xxx.bbb.21
xxx.eee
xxx.hhh.12.ddd
aaa.bbb.1.ccc
mmm.ppp
mmm.qqqq

怎么做?

6 个答案:

答案 0 :(得分:6)

一个解决方案:

sed -n '/^xxx/! { H }; // p; $ { x; s/^\n//; p }' infile

H将不以xxx开头的内容附加到保留空间,而相反的匹配则打印在// p。最后一行$恢复保留空间内容,删除前导换行符并打印。

它产生:

xxx.bbb.21
xxx.eee
xxx.hhh.12.ddd
aaa.bbb.1.ccc
mmm.ppp
mmm.qqqq

答案 1 :(得分:4)

您可以使用awk处理文件两次:

$ awk 'FNR==NR {if (/^xxx\./) {print; a[FNR]} next} !(FNR in a)' file file
xxx.bbb.21
xxx.eee
xxx.hhh.12.ddd
aaa.bbb.1.ccc
mmm.ppp
mmm.qqqq

在第一个中,我们匹配以xxx.开头的行,并且:打印它们,存储它的编号。在文件的第二次读取中,我们只是跳过那些存储的行。

答案 2 :(得分:3)

另一个awk

awk '!/^xxx/ {a[$0];next} 1; END {for (i in a) print i}' file
xxx.bbb.21
xxx.eee
xxx.hhh.12.ddd
aaa.bbb.1.ccc
mmm.ppp
mmm.qqqq

!/^xxx/如果行未以xxx开头 a[$0];next将其存储在数组a1 xxx打印行END {for (i in a) print i} a数组xxx中的结束打印行。 (没有awk '!/^xxx/ {a[++c]=$0;next} 1; END {for (i=1;i<=c;i++) print a[i]}' file xxx.bbb.21 xxx.eee xxx.hhh.12.ddd aaa.bbb.1.ccc mmm.ppp mmm.qqqq 的人)


正如fedorqui(谢谢)指出的,如果行的顺序很重要,请使用:

{{1}}

答案 3 :(得分:3)

对于那些不想使用数组的人来说,另一个问题是:

$ awk 'NR == FNR { if (/^xxx/) print; next } !/^xxx/' top.txt top.txt
xxx.bbb.21
xxx.eee
xxx.hhh.12.ddd
aaa.bbb.1.ccc
mmm.ppp
mmm.qqqq

NR == FNR { if (/^xxx/) print; next }首先,打印以xxx开头的行 !/^xxx/第二遍,打印行不以xxx开头

答案 4 :(得分:2)

使用 grep

grep "^xxx" File > NewFile && grep -v "^xxx" File >> NewFile

将以xxx开头的所有行重定向到文件NewFile。然后使用not starting grep xxx行并附加到NewFile

它在命令之间使用&&,因此如果前者以错误状态退出,则不会执行。{/ p>

答案 5 :(得分:1)

sed '/^xxx/!{H;$!d;}
     ${x;s/.//;}' YourFile

使用d行为(循环而不进一步在脚本中)