awkを使用して、現在の行と前の行フィールドの単純な数学演算の結果に基づいて文字列を印刷または省略します。

awkを使用して、現在の行と前の行フィールドの単純な数学演算の結果に基づいて文字列を印刷または省略します。
1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.92 5.10    22.36   52.79   36.94
1529.93 5.24    22.36   52.80   36.94
1529.94 6.05    22.36   52.80   36.94
1529.95 6.27    22.36   52.80   36.94
1529.95 7.01    22.36   52.80   36.94
1529.96 7.26    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.03   22.35   52.80   36.94
1530.23 26.24   22.34   52.80   36.94
1530.26 27.10   22.35   52.81   36.95

この種のファイルがあります。私が必要とするのは、2番目のフィールドの整数が前の行の2番目のフィールドの同じ数字と等しくない場合は、各行を印刷することです。たとえば、次の2行は次のようになります。

1529.94 6.05    22.36   52.80   36.94
1529.95 6.27    22.36   52.80   36.94

...最初の行だけを印刷し、2行目はスキップしたいと思います。 2番目のフィールド番号は約1300に増加してから1に減少します。

awk substr() 関数を試してみましたが、まだ機能しないようです。

awk -F. '{for (i=NR;i<3814;i++) {i=1 n=(substr($2,4))}{i=i+1 v=(substr($2,4))} {if ((n+v)%2=1) print $0} {i++}}' test.csv

答え1

申し訳ありません。あなたのawk答えはまったく役に立ちません。あなたが表現した要件とは全く異なります。

  • フィールド区切り文字は「.」ではなく空白にすることができます。
  • 不要な10進解析substr()
  • 素数を整数に丸めるには、int()

したがって、コードは次のようになります。

awk 'int($2)!=prev{
  print
  prev=int($2)
}'

1行にするには「;」が必要です。

awk 'int($2)!=prev{print;prev=int($2)}'

結果:

1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93  
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.92 5.10    22.36   52.79   36.94
1529.94 6.05    22.36   52.80   36.94
1529.95 7.01    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.03   22.35   52.80   36.94
1530.26 27.10   22.35   52.81   36.95

正しいですか?

答え2

使用しても問題ない場合は、以下を使用してくださいsed

sed -E '1p;N;/^[^ ]+ +([0-9]+)\..*\n[^ ]+ +\1\./D;h;s/.*\n//p;x;$d;D' test.csv

このN;P;Dモードでは、常に2行を同時に処理できます。長い正規表現は、2 番目のフィールドで同じ整数を持つ 2 行を見つけ、次の行に進み、そうでない場合は、2 番目の行を印刷して続行します。詳細な説明はリクエストに応じて利用可能です。

フィールド区切り文字が空白以外のタブの場合は、パターンを調整できます。

答え3

使用幸せ(以前のPerl_6):2番目の例

raku -e 'my @a = lines.rotor(2 => -1); for @a {.[0].put if .words[1].Int != .words[6].Int};'    

または

raku -e 'my @a = lines.rotor(2 => -1); for @a -> $a {$a.[0].say when $a.words[1].Int != $a.words[6].Int };' 

上記のRakuコードは、OPタイトルを文字通り解釈したものです。線のペアを接続しrotor、重なる部分を作成し、線の0,1ペア、1,2ペア、2,3ペアなどを作成するために使用されます。@a一対の行を含む配列の各位置に対して、Int2番目の列のEger同等性の条件付きテストを実行します。 sが等しくない場合、ペアをInt構成する行の最初の要素(行)はout-ですput

このアプローチの1つの注意点は、rotor基本的に完全に「グループ化された」要素のみが返されることです。したがって、すべての末尾の「要素クラスタ」が@a配列から除去される。質問のタイトルは「...現在の行と前の行のフィールド間の単純な数学計算...」しかし、この答えは厳密なペアリングを強制します(最後の行はペアリングされません)。この答えがどんな場合でも役に立つことを願っています。

出力例:

1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.93 5.24    22.36   52.80   36.94
1529.95 6.27    22.36   52.80   36.94
1529.96 7.26    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.24   22.34   52.80   36.94

https://raku.org

答え4

使用幸せ(以前のPerl_6)

raku -e 'my @a = lines.map(*.words); my %seen; for @a[*].map(*.[1].Int) {   \
         %seen.=append: ( $_ => $++ ) }; for %seen.values.map(*.min).sort -> $a {  \
         @a[$a].join("\t").put };' 

または

raku -e 'my @a = lines>>.words;  my @b = @a.map(*.[1].Int).pairs.unique( :as(*.value) ); \
         @b.=map(*.key); for @b -> $a {@a[$a].join("\t").put};'

つまり、lines個別に単語に分けて配列@aに格納されます。

(上記の最初の例):%seenハッシュが宣言されました。各行の2番目の列の場合に変換され、Intそれぞれは太い矢印構文を使用してキーと値のペアになりますInt。ここでasキーとゼロインデックスの行番号はです。これらのキーと値のペアはハッシュに追加されます。ハッシュのキーは一意である必要があるため、同じキーに複数の行番号が追加されます。最後に、ハッシュを繰り返して行番号を抽出し、それを位置インデックスとして使用して、配列内の一致する行のみを印刷することによってデータが出力されます。=>Intvalue%seenIntput%seenvaluesmin$a@a[$a]@a

上記の2番目の例:各行の最初の列はに変換され、行番号をキーと値として使用してさらにに変換さIntれます。その後、これに基づいて比較されます。その後、各配列要素で配列を個別に上書きすると、行番号が復元されます。これらは、上記のように行配列をインデックス付けするために使用されます。pairsIntpairsunique:as(*.value)@b@b.=map(*.key)keykey@a

出力例:

1529.89 1.05    22.36   48.78   33.8
1529.91 2.05    22.36   52.79   36.93
1529.92 3.06    22.36   52.80   36.93
1529.92 4.25    22.36   52.79   36.94
1529.92 5.10    22.36   52.79   36.94
1529.94 6.05    22.36   52.80   36.94
1529.95 7.01    22.36   52.80   36.94
1529.97 8.11    22.36   52.80   36.94
1529.99 9.22    22.35   52.80   36.94
1530.00 10.12   22.36   52.80   36.94
1530.02 11.26   22.36   52.80   36.94
1530.03 12.18   22.36   52.80   36.94
1530.04 13.12   22.36   52.81   36.94
1530.06 14.04   22.36   52.81   36.95
1530.10 16.21   22.36   52.81   36.94
1530.11 17.17   22.35   52.80   36.94
1530.12 18.09   22.35   52.81   36.94
1530.14 19.19   22.35   52.81   36.94
1530.15 20.19   22.35   52.80   36.94
1530.17 21.24   22.35   52.81   36.94
1530.18 22.05   22.35   52.81   36.95
1530.20 23.14   22.35   52.81   36.95
1530.21 24.14   22.35   52.81   36.94
1530.23 25.23   22.35   52.80   36.94
1530.23 26.03   22.35   52.80   36.94
1530.26 27.10   22.35   52.81   36.95

https://raku.org

関連情報