我有一个这样的文件:
aaa.bbb.1.ccc
xxx.bbb.21
mmm.ppp
xxx.eee
mmm.qqqq
xxx.hhh.12.ddd
我想通过一个简单的命令(使用xxx.
,sed
,awk
...)移动文件顶部以grep
开头的所有行
所以我的新文件将如下所示:
xxx.bbb.21
xxx.eee
xxx.hhh.12.ddd
aaa.bbb.1.ccc
mmm.ppp
mmm.qqqq
怎么做?
答案 0 :(得分:6)
一个sed解决方案:
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
将其存储在数组a
中
1
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
行为(循环而不进一步在脚本中)