我正在处理一项任务,在Unix中操作文本,但我不知道我将如何做到这一点。我打算用sed。这是我想做的事。
我有这个文字。
BS111
xxxxx
yyyyy
zzzzz
BS112
xxxxx
yyyyy
zzzzz
BS113
xxxxx
yyyyy
zzzzz
so on.. with this kind of format
我希望它像:
BS111 xxxxx
BS111 yyyyy
BS111 zzzzz
BS112 xxxxx
BS112 yyyyy
BS112 zzzzz
BS113 xxxxx
BS113 yyyyy
BS113 zzzzz
so on.. with this kind of format
BS *及其数据几乎发生了数百次。所以我认为最好的方法是使用脚本。预先感谢您的帮助。
答案 0 :(得分:3)
使用awk:
awk '/^BS/{v=$0;next} {print (/^$/) ? $0 : v, $0}' file.txt
BS111 xxxxx
BS111 yyyyy
BS111 zzzzz
BS112 xxxxx
BS112 yyyyy
BS112 zzzzz
BS113 xxxxx
BS113 yyyyy
BS113 zzzzz
答案 1 :(得分:3)
这可能适合你(GNU sed):
sed -r '/^BS/{h;d};/./!b;G;s/(.*)\n(.*)/\2 \1/' file
答案 2 :(得分:2)
尝试awk
awk '/^BS/{i=$0; next;} {if(length($0)) printf("%s ",i); print $0}' <filename>
更新
'/ ^ BS / {I = $ 0; next;} {if(length($ 0))printf(“%s”,i); print $ 0}'记住,在awk中,{...}
表示一组动作。 /pattern/{...}
表示如果找到某个模式,请执行{...}
次操作。
/^BS[0-9]/
将在每一行中搜索模式。如果找到模式,i
(awk中的变量)将使用模式更新($ 0是完整行),next
将立即移动到下一行。所以{{1}中的下一组操作如果找到模式,将跳过}}。所以{if(...}
将始终包含最后一个模式值,如果一行包含模式,除了更新i之外,该行的下一组操作将不会发生。
下一组操作是i
如果,该行包含文字,if(length($0))
打印$ 0 printf("%s ",i); print the last found pattern, And then
我prints the original line. So for an empty line, only an empty line is printed, if some text is there, first the
最后找到的图案`打印,然后是原始行打印出来。顺便说一下,sputnick的解决方案也在做同样的事情,只是以更紧凑的形式。所以你也可以解剖那个也是为了好玩。希望我很清楚,请随时询问您需要知道的任何内容
答案 3 :(得分:1)
在sed中你可以这样做:
sed -n -r '/^BS[0-9]{3}/{h;d};/./G;s/(.*)\n(.*)/\2 \1/p' test.txt
-n
表示除非通过p
命令告知,否则sed不会输出任何内容
-r
表示使用扩展正则表达式。
/^BS[0-9]{3}/{h;d}
匹配以BS开头的行和三个数字,h
命令将模式放入保留缓冲区(复制它以便以后插入)。 d
命令删除匹配的行。
/./G
匹配任何一行。 G
命令附加保持缓冲区的内容(在本例中为BSxxx)。 s/(.*)\n(.*)/\2 \1/p
匹配当前行和下一行,切换它们并删除换行符。最后,p
命令打印生成的行