ここで望むのは、3番目の行が共通に並んでいるすべての行を表示し、この行セットに基づいて出力を提供することです。 (このテーブルには一般的な3行目以外に他のプロパティがありますが、今は見ていません。)出力を見る前に、これらの行グループを見てみましょう。私たちが持っているなら
入力する:
0.016 0.032 1
0.032 0.048 1
0.048 0.064 1
0.064 0.08 1
0.08 0.096 1
0.096 0.112 1
0.112 0.128 0
0.128 0.144 0
0.144 0.16 0
0.16 0.176 0
0.176 0.192 0
0.192 0.208 0
これは、2つの行セットがあることを意味します。
共通の3番目の列値を持ち、1
0.016 0.032 1
0.032 0.048 1
0.048 0.064 1
0.064 0.08 1
0.08 0.096 1
0.096 0.112 1
2番目は共通の0
価値を持っています。
0.112 0.128 0
0.128 0.144 0
0.144 0.16 0
0.16 0.176 0
0.176 0.192 0
0.192 0.208 0
これらのそれぞれについて、3つの値を維持したいと思います。
最初の行 最初の列
最後の行の2番目の列
共通の3番目の列値
これは最終的に私たちに
希望の出力:
0.016 0.112 1
0.112 0.208 0
答え1
Perlが救出に来る!
perl -ane '
sub out { print "@_\n" }
if ($F[2] != $three) {
out($one, $two, $three) if defined $one;
($one, $three) = @F[0, 2];
}
$two = $F[1];
END { out($one, $two, $three) }
' < input > output
-n
入力を1行ずつ読み、各行に対してコードを実行します。-a
各行をスペースの @F 配列に分割します。- 最初の行の出力をスキップします
if defined $one
(3番目の列は前の列とは異なりますが、まだ出力する項目はありません)。 - 最後のブロックを印刷するにはENDブロックが必要です。
答え2
私はそれを使ってそれをしましたawk
:
awk 'BEGIN{f=0;OFS=" ";t=0;} {if(f == 0 && $3 == 1) {ff=$1;f=1;next} if(f==1 && $3 == 1) {r=$2;} \
if(t == 0 && $3 == 0) {print ff,r,1;ff=$1;t=1;next} if(t==1 && $3 == 0) {r=$2;}} END{print ff,r,0}' file
大きく見えますが、方法は簡単です。最後の列が 1 か 0 かを確認し、最初の行の最初の列と最後の行の 2 番目の列を印刷します。
より短いバージョン:
awk 'BEGIN{f=0;OFS=" ";t=0;} {if($3 == 1) {if(f==0){ff=$1;f=1;next} else{r=$2;}} \
else{if(t==0){print ff,r,1;ff=$1;t=1;next} else{r=$2;}}} END{print ff,r,0}' file
最初にfとtの値は0で、ffは最初の$3==0
最初の列の合計と同じでf=1
、次の行にこれを使用しますr=$2
。についても同様です$3==0
。
答え3
Perl
ファイルを読み、正規表現を実行するだけです。
$ perl -0777 -pe 's/^(\H+).*\h(\d+)\n(?:.*\h\2\n)*(?:.*\h(\H+)\h+\2$)/$1 $3 $2/mg' inp.file
出力:
0.016 0.112 1
0.112 0.208 0
説明する:
- ファイル全体を単一のレコードにマージし、正規表現
$_
操作を実行します。 - 正規表現は、デフォルトで最後のフィールドが一致するテキストブロックを検索し、そのブロックで機能します。
- 3つの正規表現部分でブロックを調べます。
- a) 最初の改行文字のブロックの最初の部分。
- b)(オプション)2番目の部分、最後のフィールドが最初の部分と一致するゼロ行以上。
- c) 最後のフィールドが最初の部分の最後のフィールドと一致する 3 番目の部分。同時に、3番目の部分の2番目のシーンを録音します。
- d) ブロック全体を最初の部分の最初のフィールドに置き換え、次に3番目の部分の2番目のフィールド、最初の部分の最後のフィールドに置き換えます。
これはPerl
上記と同じコードですが、明確にするために別々のコメントが挿入され、フォーマットされています。
$ perl -0777 -pe '
s{
^(\H+).*\h(\d+)\n (?#:the first row.)
(?:.*\h\2\n)* (?#:0 or more rows, whose last field matches the 1st row"s last.)
(?:.*\h(\H+)\h+\2$) (?#:the last row, whose last field matches the 1st row"s last.)
}{
my($first_row_first_col, $last_row_second_col, $common_index) = ($1, $3, $2);
join " ", $first_row_first_col, $last_row_second_col, $common_index;
}gemx;
' inp.file