根据模式重新排列数据

根据模式重新排列数据

我有一个这样的文件

A1: abc.com B1: Hi there
B1: Your Test mail  A1: gml.com
B1: Your new mail   A1: hml.com
A1: def.com B1: Test email
B1: hello world A1: yml.com

我想始终先选择零件,A1: <string>然后再选择B1: <string>零件。

我已经尝试过grepawk喜欢下面的

 grep -Po '(?<=A1:)\W*\K[^ ]*' file.txt 
 awk -F"A1:|B1:" '{print $1 $2}' file.txt 

但他们没有给出确切的结果

我希望输出是这样的:

 A1: abc.com   B1: Hi there
 A1: gml.com   B1: Your Test mail   
 A1: hml.com  B1: Your new mail 
 A1: def.com  B1: Test email
 A1: yml.com  B1: hello world

答案1

您可以保留以原样开头的行A1,并重新排列以B1

# if -E or -r is not supported: sed 's/\(B1:.*\)\(A1:.*\)/\2 \1/' ip.txt
$ sed -E 's/(B1:.*)(A1:.*)/\2 \1/' ip.txt
A1: abc.com B1: Hi there
A1: gml.com B1: Your Test mail  
A1: hml.com B1: Your new mail   
A1: def.com B1: Test email
A1: yml.com B1: hello world 


awk

$ awk -F'A1:' '{print $1 ~ /B1:/ ? FS $2 " " $1 : $0}' ip.txt
A1: abc.com B1: Hi there
A1: gml.com B1: Your Test mail  
A1: hml.com B1: Your new mail   
A1: def.com B1: Test email
A1: yml.com B1: hello world 

如果第一个字段包含B1:,则重新排列字段,否则按原样打印输入行

答案2

我们可以使用以下方法来做到这一点:

perl -F'/(A1:|B1:)/' -lane '
   my %h = @F[1..$#F];
   print map { "$_$h{$_} " } qw/A1: B1:/;
' input.txt

输出:

A1: gml.com B1: Your Test mail   
A1: abc.com  B1: Hi there 
A1: hml.com B1: Your new mail    
A1: def.com  B1: Test email 
A1: yml.com B1: hello world

解释:

  • 拆分 A1: 和/或 B1: 上的每条记录,并且还包括“拆分器”。
  • @F 数组中的第一个字段应被忽略。因此,@F 数组中有偶数个元素,然后将其存储为散列 %h,键为“A1:”和“B1:”。
  • 现在,我们通过匿名数组 qw/.../ 迭代指定的顺序,并将结果打印到 stdout。

相关内容