コマンドに awk 変数を渡し、出力を読み込みます。

コマンドに awk 変数を渡し、出力を読み込みます。

文字列で区切られた部分でファイルをソートしたいのですが、awkで処理するのはもっと大きな部分です。

区切り文字の間に行を保存し、asortを使用して並べ替えることができることを読みましたが、2番目の列を使用して並べ替える必要があります。

区切り記号間の出力を変数(K) 次に、変数値をコマンドにパイプします。|、最後に出力を読み取り、処理して印刷します。

print variable|"sort -k2,2"|getline vしかし、並ぶ(?)詰まっています。

コマンドを実行できます。もっと醜い私は関数を使用する方法を使用しましたが、system()コマンドに変数を渡すにはechoを使用する必要があると思いましたが、出力は変数vには保存されず、エラーコードに保存されました。

$ awk 'BEGIN{ cmd="sort -k2,2"; k="1\tB\n2\tA"; v=system("echo \""k"\" | "cmd); print "OK: "v}'
2       A
1       B
OK: 0

これより良いprint k|command(removing)を使用してコマンドを実行します|getline vが、print "OK"サブコマンドが出力される前に完了します。出力は変数に保存されません。V

$ awk 'BEGIN{ cmd="sort -k2,2"; k="1\tB\n2\tA"; print k|cmd; print "OK: "v}'
OK:
2       A
1       B

コマンド出力を変数に保存するにはどうすればよいですか?それとも、少なくとも続行する前に前のサブコマンドが完了するのを待つことができますか?

答え1

これがあなたが望むものですか(GNU awkを使用して共同プロセス)?

$ cat tst.awk
BEGIN {
    cmd = "sort -k2,2"
    k = "1\tB\n2\tA"

    print k |& cmd
    close(cmd, "to")

    while ((cmd |& getline line) > 0) {
        v = v line ORS
    }
    close(cmd)

    print "OK:"
    printf "%s", v
}

$ awk -f tst.awk
OK:
2       A
1       B

上記でGNU awkが使用されていたので(そしてすでに言及されています)分類()あなたの質問では、これはgawkに固有のものです。 gawkにはすでにソート機能が組み込まれているので、これを行う必要はありません。次にソートsort上記のように、各呼び出しに対してサブシェルを作成する代わりに:

$ cat tst.awk
BEGIN {
    k = "1\tB\n2\tA"

    split(k,lines,/\n/)
    for (i in lines) {
        lines[i] = gensub(/[^\t]*\t([^\t]+)/,"\\1\t&",1,lines[i])
    }

    PROCINFO["sorted_in"] = "@val_str_asc"
    for (i in lines) {
        v = v gensub(/[^\t]\t/,"",1,lines[i]) ORS
    }

    print "OK:"
    printf "%s", v
}

$ awk -f tst.awk
OK:
2       A
1       B

しかし、私の考えでは、これはやろうとしているより難しい作業のいくつかの単純化されたバージョンであり、実際には二次プロセスが必要です。

答え2

この記事に記載されている問題に対する解決策に興味がある人コメント:

awkは他のコマンド(squeueなど)の出力を処理しており、他のユーザーの操作に関する完全な情報は必要ありません。走りながら参加できます。

alias squeue="_squeue() {
    /usr/bin/squeue --format=\"%.8i %.9P %.20j %.10u %.2t %.10M %.10L %.6D %R\" \$@ \
    | awk '
        BEGIN { cmd=\"sort -k2,2 -k5,5 -k4,4\" }
        function sort(buf) {
            sorted=\"\"
            gsub(\"^\"ORS\"*|\"ORS\"{2,}|\"ORS\"*$\", \"\", buf)
            if (length(buf)>0) {
                print buf |& cmd
                close(cmd, \"to\")
                while ((cmd |& getline line) > 0) {
                    sorted = sorted line ORS
                }
                close(cmd)
            }
            return sorted
          }
          NR <= 1 { print; next }
          /'\$USER'/ {
              printf(\"%s\", sort(buf))
              buf=\"\"
              print
              partition=\$2; user=\$4; st=\$5;
              next
          }
          { buf = buf ORS \$0 }
          END {
              printf(\"%s\", sort(buf))
          }
        ' \
    | awk '
        BEGIN { partition=\"\"; user=\"\"; st=\"\"; c=0; n=0; }
        function print_count() {
            if(c>0) { print \" (count: \"c\" jobs, \"n\" nodes)\"; c=0; n=0; }
        }
        NR <= 1 { print \$0; next }
        /'\$USER'/ {
            print_count()
            print;
            next
        }
        \$2!=partition || \$4!=user || \$5!=st {
            print_count()
            printf(\"%-98s\", substr(\$0,0, 98));
            partition=\$2; user=\$4; st=\$5;
        }
        { n+=\$8; c++ }
        END {
            print_count()
        }' \
    |  sed '/(count: .*)$/{s/.*/\x1b[90m&\x1b[0m/p;d};
            /\s'\$USER'\s\+[^R]\+\s/{s/.*/\x1b[1m&\x1b[0m/p;d}'
}
_squeue"

関連情報