Awk sed中的多行处理

Awk sed中的多行处理,awk,sed,Awk,Sed,有人能告诉我如何从这样的输入中获取信息吗: 输出如下: GOR-美元、GOR-欧元、卖出、买入都是变量 我知道这并不是你所要求的,但我想我应该提供一种用Perl实现的方法——这是我非常喜欢的一种解析和处理文本的方法。(您可以像使用sed一样使用它,但要做的更多) 我们使用正则表达式“检测”标题行并捕获它,然后每隔一行将其打印为前缀 #!/usr/bin/perl use strict; use warnings; my $header; while ( my $line = <D

有人能告诉我如何从这样的输入中获取信息吗:


输出如下:




GOR-美元、GOR-欧元、卖出、买入都是变量

我知道这并不是你所要求的,但我想我应该提供一种用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  
#/usr/bin/perl
严格使用;
使用警告;
我的$header;
while(我的$line=){
chomp$行;
如果($line=~m/\w{3}-\w{3}:/){
$header=$line;
}
否则{
打印$header.$行“\n”;
}
}
__资料__
GOR-美元:
购买24.2000 1200+380(98)578-2574繁忙
上午出售25.0000 20000+380(99)444-4426
出售25.1000 17 500+380(98)200-3003亚历克斯
GOR-欧元:
销售25.1000 17500+380(98)200-3003澳门币
购买24.2000 1200+380(98)578-2874喷气式飞机
销售25.0000 20000+380(99)444-4126湿
出售25.0000 20000+380(99)444-4226宠物
出售26.0000 20000+380(99)444-1226彼得

我知道这不是你所要求的,但我想我会提供一种用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  
#/usr/bin/perl
严格使用;
使用警告;
我的$header;
while(我的$line=){
chomp$行;
如果($line=~m/\w{3}-\w{3}:/){
$header=$line;
}
否则{
打印$header.$行“\n”;
}
}
__资料__
GOR-美元:
购买24.2000 1200+380(98)578-2574繁忙
上午出售25.0000 20000+380(99)444-4426
出售25.1000 17 500+380(98)200-3003亚历克斯
GOR-欧元:
销售25.1000 17500+380(98)200-3003澳门币
购买24.2000 1200+380(98)578-2874喷气式飞机
销售25.0000 20000+380(99)444-4126湿
出售25.0000 20000+380(99)444-4226宠物
出售26.0000 20000+380(99)444-1226彼得
使用
sed
工作原理:

  • /:/{h;d}

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

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

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

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

sed -E -e '/:/{h;d}' -e G -e 's/(.*)\n(.*)/\2 \1/' file
使用
awk
工作原理:

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

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

  • 打印hdr,$0

    对于所有其他行,我们先打印标题,然后打印行

使用
sed
工作原理:

  • /:/{h;d}

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

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

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

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

sed -E -e '/:/{h;d}' -e G -e 's/(.*)\n(.*)/\2 \1/' file
使用
awk
工作原理:

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

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

  • 打印hdr,$0

    对于所有其他行,我们先打印标题,然后打印行


假设示例输入中的仅为句点的行实际上不存在,但用于指示与它们周围的行类似的后续行:

$ 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

假设示例输入中仅为句点的行实际上不存在,但用于指示与它们周围的行类似的后续行:

$ 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

您可以在
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

您可以在
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

必须是
sed
?我想看看perl…我宁愿用
awk
来做,这样好吗?不要用sed来做。sed用于单行上的简单替换。20世纪70年代中期,当awk发明时,所有用于跨多行操作的神秘sed语言结构都已过时。如今,人们继续把它们当作脑筋急转弯,看看他们是否能想出神奇的咒语,使他们产生所需的输出。它必须是
sed
?我想看看perl…我宁愿用
awk
来做,这样好吗?不要用sed来做。sed用于单行上的简单替换。20世纪70年代中期,当awk发明时,所有用于跨多行操作的神秘sed语言结构都已过时。今天,人们继续使用它们,主要是作为一种脑筋急转弯,看看他们是否能想出神奇的咒语,使他们产生所需的输出。谢谢你,约翰1024,最后,对于Freebsd sed,我使用
sed'/:/{h;d;};Gs/\(.*)\n\(.*)/\2\1/'文件
谢谢你,John1024,最后我使用了
sed'/://{h;d;}免费的bsd sed;Gs/\(.*)\n\(.*)/\2\1/'文件