在linux中如何移动数字并与列和行匹配?
嗨,伙计们,我有一个问题??我想在另一个文件中移动列,并与行和列匹配,然后放在准确的位置 输入文件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 我试了很多:(在linux中如何移动数字并与列和行匹配?,linux,awk,Linux,Awk,嗨,伙计们,我有一个问题??我想在另一个文件中移动列,并与行和列匹配,然后放在准确的位置 输入文件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 我试了很多:( 你能帮我吗?我写了一个快速而肮
你能帮我吗?我写了一个快速而肮脏的解决方案,适用于给定的示例输入 命令:
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/ / /}'
在我的控制台上测试:
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 -
实际上,逻辑部分相对简单,在您的示例中,许多代码只是用于以相同的格式进行输出。您可以使用
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"," ")
}
}
请参见此处的操作:
注:
report.awk
的文件中,然后执行awk-f report.awk input_文件
HTH相关:我刚刚添加了一些评论。Thanx dude,我还有一个问题。你没有写任何文件名。你能告诉我把我的文件名(文件1和文件2)放在哪里吗。把上面的内容放在一个像
report.awk
这样的文件中,然后做awk-f report.awk INPUT\u file
。它只需要第一个文件作为输入。
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/ / /}'
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 -
# 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"," ")
}
}