명령에 awk 변수를 전달하고 출력을 읽습니다.

명령에 awk 변수를 전달하고 출력을 읽습니다.

문자열로 구분된 부분으로 파일을 정렬하고 싶지만 awk에서 처리하기에는 더 큰 부분입니다.

구분 기호 사이에 행을 저장한 다음 asort를 사용하여 정렬할 수 있다는 내용을 읽었지만 두 번째 열을 사용하여 정렬해야 합니다.

구분 기호 사이의 출력을 변수(케이) 그런 다음 변수 값을 명령에 파이프합니다.|, 마지막으로 출력을 읽고 처리한 후 인쇄합니다.

그러나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"

관련 정보