1

このトピックに関する明確なチュートリアルが見つかりません。次のような入力ファイルがあるとします。

1 abc
1 def
1 ghi
1 lalala
1 heyhey
2 ahb
2 bbh
3 chch
3 chchch
3 oiohho
3 nonon
3 halal
3 whatever

最初に出現した列 1 の最大数、つまり 6 回出現した「3」を見つけたいとします。次に、この数値 (つまり 6) を別のスクリプトに入力して、ファイルを調べて計算を行う必要があります。これを行う方法は何ですか?

基本的に、ファイルを調べて "max" を見つけてから、メイン関数でヘルパー関数を呼び出す関数を書くことが可能かどうか疑問に思います。また、ヘルパー関数内で $(...) を実行して「awk」または他のシステム関数を呼び出すことは可能でしょうか?

4

2 に答える 2

1
awk 'NR == FNR {nums[$1]++; next} ! flag {flag = 1; for (num in nums) {if (nums[i] > max) {max = nums[i]}}} {print max * $3}' filetomax filetoprocess

ここでは、複数の行に分かれています。

awk '
    NR == FNR {
        nums[$1]++;
        next
    } 
    ! flag {
        flag = 1; 
        for (num in nums) {
            if (nums[i] > max) {
                max = nums[i]
            }
        }
    } 
    {
        print max * $3
    }
' filetomax filetoprocess

ここでは、以前に見た数の最大値を見つけるために同じ操作を行っています。メインブロックとブロックを使用する代わりに、ENDあるファイルを処理してから別のファイルを処理するためによく使用される手法を使用しています。すべてのファイルの行ごとに増分されるレコード番号()は、新しいファイルごとにリセットされるファイルレコード番号()と等しいため、このNR == FNR条件は最初のファイルが読み取られている間のみ真になります。この状態に関連するブロックで、各番号が表示される回数を数えます。このステートメントにより、実行がループし、ファイルから次の行が読み取られます。2番目のファイルに到達すると、条件は真ではなくなり、このブロックはスキップされます。NRFNRnext

次の条件付き(! flag)は、変数の内容がtrueであるかどうかを確認します。設定されていないので誤りです。感嘆符は条件を否定するため、この時点で実行はこのブロックに移動します。これでフラグが設定され、次に条件がチェックされたときにこのブロックはスキップされます。ループは、他の質問に対する私の回答のように、どの番号が最も頻繁に出現したforかを確認します。

これで、2番目のファイルを任意の方法で処理でき、maxこの処理中に変数を使用できるようになります。私は単にprintそれを説明するためにステートメントを使用しました。END通常どおりに1つ以上のブロックを含め、ブロックセレクター条件を引き続き使用できます。ブロックは表示しませんBEGINが、必要な初期化のために、このスクリプトの先頭にブロックを追加できます。最初のファイルの処理は、BEGINを使用してブロックで実行できた可能性があることに注意してくださいgetline。これは、同じことを達成するための単なる別の手法です。

ファイル名は、処理される順序でリストされています。私が「filetomax」と呼んでいる最大数を見つけるためのファイル。「filetoprocess」と呼ばれる、メイン処理を実行する2番目のファイル。

于 2012-06-04T01:25:53.390 に答える
0

これにはパイプを使用します。最初のプロセスの stdout を取得し、2 番目のプロセスの stdin に接続します。

awk ... | awk ...
于 2012-06-03T23:36:47.353 に答える