sed中的多行处理

时间:2015-02-09 22:13:30

标签: awk sed

有人可以指出我如何从这样的输入中得到:


GOR - USD:  
Buy 24.2000 1 200 +380 (98) 578-2574 Busy  
Sell 25.0000 20 000 +380 (99) 444-4426 Morn  
Sell 25.1000 17 500 +380 (98) 200-3003 Alex  
.  
.  
GOR - EUR:  
Sell 25.1000 17 500 +380 (98) 200-3003 Moy  
Buy 24.2000 1 200 +380 (98) 578-2874 Jet  
Sell 25.0000 20 000 +380 (99) 444-4126 Wet   
Sell 25.0000 20 000 +380 (99) 444-4226 Pet  
Sell 26.0000 20 000 +380 (99) 444-1226 Peter   

输出如下:


GOR - USD: Buy 24.2000 1 200 +380 (98) 578-2574 Busy  
GOR - USD: Sell 25.0000 20 000 +380 (99) 444-4426 Morn  
GOR - USD: Sell 25.1000 17 500 +380 (98) 200-3003 Alex  
.  
.  
GOR - EUR: Sell 25.1000 17 500 +380 (98) 200-3003 Moy  
GOR - EUR: Buy 24.2000 1 200 +380 (98) 578-2874 Jet  
GOR - EUR: Sell 25.0000 20 000 +380 (99) 444-4126 Wet  
GOR - EUR: Sell 25.0000 20 000 +380 (99) 444-4226 Pet  
GOR - EUR: Sell 26.0000 20 000 +380 (99) 444-1226 Peter

GOR - 美元,GOR - 欧元,卖出,买入 - 是变数。

4 个答案:

答案 0 :(得分:2)

我知道这不是你提出的要求,但我认为我会提供一种在Perl中实现它的方法 - 这是我非常喜欢的一种解析和处理文本的方式。 (您可以像sed一样使用它,但可以使用更多)。

我们使用正则表达式“检测”标题行并捕获它,然后我们将每个其他行打印为前缀。

#!/usr/bin/perl

use strict;
use warnings;

my $header;
while ( my $line = <DATA> ) {
     chomp $line;
     if ( $line =~ m/\w{3} - \w{3}:/ ) {
          $header = $line;
     }
     else {
         print $header . $line,"\n";
     }
}


__DATA__
GOR - USD:  
Buy 24.2000 1 200 +380 (98) 578-2574 Busy  
Sell 25.0000 20 000 +380 (99) 444-4426 Morn  
Sell 25.1000 17 500 +380 (98) 200-3003 Alex  
GOR - EUR:  
Sell 25.1000 17 500 +380 (98) 200-3003 Moy  
Buy 24.2000 1 200 +380 (98) 578-2874 Jet  
Sell 25.0000 20 000 +380 (99) 444-4126 Wet   
Sell 25.0000 20 000 +380 (99) 444-4226 Pet  
Sell 26.0000 20 000 +380 (99) 444-1226 Peter  

答案 1 :(得分:2)

使用sed

$ sed -r '/:/{h;d}; G; s/(.*)\n(.*)/\2 \1/' file
GOR - USD:   Buy 24.2000 1 200 +380 (98) 578-2574 Busy  
GOR - USD:   Sell 25.0000 20 000 +380 (99) 444-4426 Morn  
GOR - USD:   Sell 25.1000 17 500 +380 (98) 200-3003 Alex  
GOR - USD:   .  
GOR - USD:   .  
GOR - EUR:   Sell 25.1000 17 500 +380 (98) 200-3003 Moy  
GOR - EUR:   Buy 24.2000 1 200 +380 (98) 578-2874 Jet  
GOR - EUR:   Sell 25.0000 20 000 +380 (99) 444-4126 Wet   
GOR - EUR:   Sell 25.0000 20 000 +380 (99) 444-4226 Pet  
GOR - EUR:   Sell 26.0000 20 000 +380 (99) 444-1226 Peter

工作原理:

  • /:/{h;d}

    任何包含冒号的行都会保存到保留空间。

  • G; s/(.*)\n(.*)/\2 \1/

    对于所有其他行,我们将保留空间附加到该行,然后交换订单,以便首先打印保留空间中的内容。

对于Mac OSX或其他BSD系统,请尝试:

sed -E -e '/:/{h;d}' -e G -e 's/(.*)\n(.*)/\2 \1/' file

使用awk

$ awk '/:/{hdr=$0;next} {print hdr,$0}' file
GOR - USD:   Buy 24.2000 1 200 +380 (98) 578-2574 Busy  
GOR - USD:   Sell 25.0000 20 000 +380 (99) 444-4426 Morn  
GOR - USD:   Sell 25.1000 17 500 +380 (98) 200-3003 Alex  
GOR - USD:   .  
GOR - USD:   .  
GOR - EUR:   Sell 25.1000 17 500 +380 (98) 200-3003 Moy  
GOR - EUR:   Buy 24.2000 1 200 +380 (98) 578-2874 Jet  
GOR - EUR:   Sell 25.0000 20 000 +380 (99) 444-4126 Wet   
GOR - EUR:   Sell 25.0000 20 000 +380 (99) 444-4226 Pet  
GOR - EUR:   Sell 26.0000 20 000 +380 (99) 444-1226 Peter

工作原理:

  • /:/{hdr=$0;next}

    包含冒号的任何行都保存在变量hdr中。然后我们跳到下一行。

  • print hdr,$0

    对于所有其他行,我们打印标题后跟行。

答案 2 :(得分:1)

假设您的样本输入中的行只是句点并不存在但是用于表示后续行与它们周围的行类似:

$ awk 'NF>3{print hdr, $0; next} {hdr=$0}' file
GOR - USD: Buy 24.2000 1 200 +380 (98) 578-2574 Busy  
GOR - USD: Sell 25.0000 20 000 +380 (99) 444-4426 Morn  
GOR - USD: Sell 25.1000 17 500 +380 (98) 200-3003 Alex  
GOR - EUR: Sell 25.1000 17 500 +380 (98) 200-3003 Moy  
GOR - EUR: Buy 24.2000 1 200 +380 (98) 578-2874 Jet  
GOR - EUR: Sell 25.0000 20 000 +380 (99) 444-4126 Wet   
GOR - EUR: Sell 25.0000 20 000 +380 (99) 444-4226 Pet  
GOR - EUR: Sell 26.0000 20 000 +380 (99) 444-1226 Peter

答案 3 :(得分:1)

您可以在awk中使用关联数组:

awk '!/:/{a[$0]=currency} /:/{currency=$0}END{for(i in a){ print a[i],i }}' file
GOR - USD:   Sell 25.0000 20 000 +380 (99) 444-4426 Morn  
GOR - EUR:   Buy 24.2000 1 200 +380 (98) 578-2874 Jet  
GOR - EUR:   Sell 26.0000 20 000 +380 (99) 444-1226 Peter   
GOR - EUR:   Sell 25.0000 20 000 +380 (99) 444-4126 Wet   
GOR - EUR:   Sell 25.1000 17 500 +380 (98) 200-3003 Moy  
GOR - USD:   Buy 24.2000 1 200 +380 (98) 578-2574 Busy  
GOR - EUR:   Sell 25.0000 20 000 +380 (99) 444-4226 Pet  
GOR - USD:   Sell 25.1000 17 500 +380 (98) 200-3003 Alex