パターンに従ってデータを並べ替える

パターンに従ってデータを並べ替える

このようなファイルがあります。

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>を選択したいと思います。

私は次のことを試してgrepみました。awk

 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 
  • .*欲が多いので、このソリューションは次のように仮定し、A1:各行B1:で一意です。
  • (B1:.*)(A1:.*)2 つのキャプチャグループがあります。完全な式を満たすために、最初のキャプチャグループはB1:最大beforeまでのすべての文字列をキャプチャしますA1:。 2番目は、A1:行の終わりから始まる文字列をキャプチャします。
  • \2 \1キャプチャされた文字列の間にスペースを含めて並べ替えます。
  • 追加資料:https://www.gnu.org/software/sed/manual/sed.html#Back_002dreferences-and-Subexpressions


そして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 配列には偶数の要素があり、これは "A1:" キーと "B1:" キーを使用してハッシュ %h として格納されます。
  • 次に、指定された順序で匿名配列qw / ... /を繰り返し、結果をstdoutに出力します。

関連情報