このようなファイルがあります。
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に出力します。