我正在为一个类的项目工作,我们在这里有一个文件,里面有很多行描述如下所示的类
CSC 1010 - 计算机&应用
计算机和应用。先修课程:高中代数II。计算机的历史,>硬件组件,操作系统,应用软件,数据通信 3.000学分
并将其转换为
CSC1010,COMPUTERS&申请,3
我用过:
sed -n 's/^CSC /CSC/p' courses.txt > practice.txt
输出:
CSC1010 - 计算机&应用
CSC1310 - INTRO COMP PROGRAMMING ON-MAJ
CSC2010 - 计算机科学入门 CSC2310 - 计算机程序设计的原则
CSC2320 - 网站开发基金
CSC2510 - COMP SCI的理论基础 CSC3010 - 计算历史
CSC3210 - 计算机ORG&编程
CSC3320 - 系统级编程
CSC3330 - C ++编程
CSC3410 - 数据结构-CTW
CSC4110 - 嵌入式系统
CSC4120 - 机器人介绍
我也用过:
sed '/\.000 Course hours//p' courses.txt > courses10.txt
输出:
3 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4
我的问题是尝试选择sed,awk或perl是否会更好。所以,到目前为止,我已经使用sed来消除那些不是由课程名称或学分小时数组成的行。如上所述。我希望使用正则表达式对文件进行排序,并获得以“CSC”开头或包含“.000课程时间”的每一行。我想在得到输出后我可以在sed中使用一个命令从CSC开始的行末尾删除新行,并用逗号替换它。之后我会用逗号替换反斜杠。但是,要做到这一点,我想我需要使用扩展表达式,所以sed可能会出来。我正在考虑使用的正则表达式是(^CSC |[0-9]\.000)
。那么,我应该在sed,awk还是perl中这样做。如果您可以请说明为什么使用您建议的任何方法更有效率的原因。
答案 0 :(得分:2)
Perl:
while (<>) {
chomp;
print if s/^CSC\s+/CSC/ and s/\s+-\s+/,/;
printf ",%.0f\n", $1 if /^([\d.]+)\s+Credit hours/;
}
答案 1 :(得分:1)
我选择awk
,因为您希望匹配并重新格式化行,awk
非常适合:
/CSC/ { # Lines that match CSC
split($0,a,"- ") # Split the line around the hyphen and following space
gsub(/ /,"",a[1]) # Remove the spaces from the first part of the split
printf a[1]","a[2] # Print the line in required format
}
/Credit hours/ { # Lines that match Credit hours
printf ",%i\n",$1 # Print the integer value of credit hours
}
演示:
awk '/CSC/{split($0,a,"- ");gsub(/ /,"",a[1]);printf a[1]","a[2]}/Credit hours/{printf ",%i\n",$1}' file
CSC1010,COMPUTERS & APPLICATIONS,3
我更喜欢awk
到Perl
,这对此没有任何优势(或劣势)。使用sed
将是一个regexp hack,因此我远离sed
解决方案。