Как переместить число и сопоставить столбец и строки в Linux? - PullRequest
1 голос
/ 22 ноября 2011

Привет, ребята, у меня есть вопрос? Я хочу переместить столбец в другой файл и сопоставить со строками и столбцом и поставить в точное положение.

входной файл1:

COURSE NAME: Java
CREDITS: 4
200345    88
300126    78
287136    68
200138    71
COURSE NAME: Operating System
CREDITS: 4
287136    86
200138    72
200345    77
300056    78

входной файл2:

STUDENT ID        Java        Operating System      GPA
200138
200345
287136
300056
300126

нужен вывод как это:

STUDENT ID        Java        Operating System      GPA
200138             71                 72
200345             88                 77
287136             68                 86
300056             -                  78
300126             78                 -

Я набираю этот код:

awk 'NR==FNR{a[$1]=$2;next} {print $0 FS a [$1];next}' file1 file2

и его вывод будет выглядеть так:

STUDENT ID       JAVA       Operating Systems       GPA
200138 72
200345 77
287136 86
300056 78
300126 78

Я много пробовал :( Можете ли вы помочь мне?

Ответы [ 2 ]

2 голосов
/ 22 ноября 2011

Ну, вы можете сделать это с awk, но это не тривиально.Как это:

# We will save every course name in an array for the report, but first remove the 
# the unwanted space from it's name. This line only works on the COURSE NAME lines
/^COURSE NAME/ {cn=gensub(" ","_","g",gensub(".*: ","","g",$0)); crss[cn]+=1 }

# On lines which starts with a number (student id), we are saving the student ids 
# in an array (stdnts) and the students score with a "semi" multideminsional array/hash
# where the indecies are "student_id-course_name" 
/^[0-9]/ {stdnts[$1]+=1 ; v[$1 "-" cn]=$2}

# after the above processing (e.g. the last line of the input file)
END {
      # print the header, it's dynamic and uses the course names it saved earlier
      printf("%-20s","STUDENT ID");
      for (e in crss) {printf("%-20s",e)}
      printf("%-20s\n","GPA")

      # print the report
      for (s in stdnts)
          # we need to print every student id
          { printf("%-20s",s)
            for (cs in crss) {
                # then check if she had any score for every score, and print it
                if (v[s "-" cs] > 0) {
                    printf("%-20s",v[s "-" cs])
                }
                else {
                    printf("%-20s","-")
            }
          }
        printf("%-20s\n"," ")
      }
  }

Смотрите здесь в действии: https://ideone.com/AgaS8

Примечание :

  1. скрипт неоптимизировано;
  2. заменяет исходные названия курсов на без пробелов
  3. вывод таблицы студентов не отсортирован по идентификатору студента
  4. , требуется только первыйфайл в качестве ввода !Поместите вышеупомянутое в файл как report.awk, затем сделайте awk -f report.awk INPUT_FILE.

HTH

1 голос
/ 22 ноября 2011

я написал быстрое и грязное решение, работает для вашего примера ввода.

Команда:

 sed '/CREDIT/d' file1|awk 'FNR==NR{ if($0~/Java/){j++;o=0;next;}
        if($0~/Operating/){o++;j=0;next;}
        if(j){java[$1]=$2}
        if(o){os[$1]=$2}
}NR>FNR{OFS=" ";
        if(FNR==1){sub(/ /,"");print;}
        else{$2=" "
        $3=($1 in java)?java[$1]:"-";
        $4=($1 in os)?os[$1]:"-";
        print $0;
        }

}' - file2|column -t|sed -e 's/ID/ ID/' -e '2,${s/ /    /}'

test на моей консоли:

kent$  sed '/CREDIT/d' file1|awk 'FNR==NR{ if($0~/Java/){j++;o=0;next;}
        if($0~/Operating/){o++;j=0;next;}
        if(j){java[$1]=$2}
        if(o){os[$1]=$2}
}NR>FNR{OFS=" ";
        if(FNR==1){sub(/ /,"");print;}
        else{$2=" "
        $3=($1 in java)?java[$1]:"-";
        $4=($1 in os)?os[$1]:"-";
        print $0;
        }

}' - file2|column -t|sed -e 's/ID/ ID/' -e '2,${s/ /    /}'
STUDENT ID  Java  Operating  System  GPA
200138        71    72
200345        88    77
287136        68    86
300056        -     78
300126        78    -

На самом деле логическая часть относительно проста, многие коды предназначены для вывода в том же формате в вашем примере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...