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
一対の行を含む配列の各位置に対して、Int
2番目の列の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
答え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キーとゼロインデックスの行番号はです。これらのキーと値のペアはハッシュに追加されます。ハッシュのキーは一意である必要があるため、同じキーに複数の行番号が追加されます。最後に、ハッシュを繰り返して行番号を抽出し、それを位置インデックスとして使用して、配列内の一致する行のみを印刷することによってデータが出力されます。=>
Int
value
%seen
Int
put
%seen
values
min
$a
@a[$a]
@a
上記の2番目の例:各行の最初の列はに変換され、行番号をキーと値として使用してさらにに変換さInt
れます。その後、これに基づいて比較されます。その後、各配列要素で配列を個別に上書きすると、行番号が復元されます。これらは、上記のように行配列をインデックス付けするために使用されます。pairs
Int
pairs
unique
:as(*.value)
@b
@b.=map(*.key)
key
key
@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