3

我现在正在处理一项任务,在 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* 及其数据几乎出现了一百次。所以我认为最好的方法是使用脚本。预先感谢您的帮助。

4

4 回答 4

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
于 2013-05-07T09:07:23.873 回答
3

这可能对您有用(GNU sed):

sed -r '/^BS/{h;d};/./!b;G;s/(.*)\n(.*)/\2 \1/' file
于 2013-05-07T11:25:08.297 回答
2

尝试awk

awk '/^BS/{i=$0; next;} {if(length($0)) printf("%s ",i); print $0}' <filename>

更新:

'/^BS/{i=$0; 下一个;} {if(length($0)) printf("%s",i); print $0}' 记住,在 awk 中,{...}表示一组动作。/pattern/{...}表示如果找到模式,则执行{...}操作。 /^BS[0-9]/将在每一行中搜索模式。如果找到该模式,i(awk 中的变量)将使用该模式进行更新($0 是完整的行),next并将立即移至下一行。因此,{if(...}如果找到一个模式,则将跳过下一组操作。所以i将始终包含最后一个模式值,如果一行包含模式,除了更新 i 之外,将不会对该行执行下一组操作。

下一组操作是,if(length($0))如果该行包含文本,则printf("%s ",i); print the last found pattern, And then打印 $0 prints the original line. So for an empty line, only an empty line is printed, if some text is there, first thei orlast found pattern`,然后打印原始行。顺便说一句,sputnick 的解决方案也在做同样的事情,只是形式更紧凑。所以你也可以为了好玩而剖析那个。希望我很清楚,请随时询问您需要知道的任何内容

于 2013-05-07T09:05:49.163 回答
1

sed中,您可以执行以下操作:

sed -n -r '/^BS[0-9]{3}/{h;d};/./G;s/(.*)\n(.*)/\2 \1/p' test.txt

-n意味着 sed 不会输出任何内容,除非p命令告知。
-r意味着使用扩展的正则表达式。

/^BS[0-9]{3}/{h;d}匹配以 BS 和三个数字开头的行,该h命令将模式放入保存缓冲区(复制它以供以后插入)。该d命令删除匹配的行。

/./G匹配任何行。该G命令附加了保持缓冲区的内容(在本例中为 BSxxx)。s/(.*)\n(.*)/\2 \1/p匹配当前行和下一行,切换它们并删除换行符。最后p命令打印结果行

于 2013-05-07T12:02:12.347 回答