【问题标题】:Print two awk matches on one line在一行上打印两个 awk 匹配项
【发布时间】:2013-03-09 23:14:38
【问题描述】:

我正在尝试为匹配某些文本字段并以某种格式打印它们的作业制作一个 bash 脚本。我正在尝试获取课程编号、标题和学时数(从十进制转换为整数)并将其输出到名为 course_list 的文件中。

示例输入:

CSC 1010 - COMPUTERS & APPLICATIONS
Computers and Applications. Prerequisite: high school Algebra II. History of computers, hardware components, operating systems, application software, data communication. 
3.000 Credit hours

这是我所拥有的:

#!/bin/bash
awk '/CSC/ {print $1$2","$4,$5,$6,$7,$8,$9} /[0-9].(000)/ {print substr(","$1,1,2)}' courses.txt | cat >> course_list

这是我得到的输出:

CSC1010,COMPUTERS & APPLICATIONS   
,3

这是我想要的输出:

CSC1010,COMPUTERS & APPLICATIONS,3

我认为我已经很接近了,但我无法弄清楚如何在没有 \n 的情况下打印两个单独的匹配项。

【问题讨论】:

标签: bash shell awk


【解决方案1】:
$ cat file
CSC 1010 - COMPUTERS & APPLICATIONS
Computers and Applications. Prerequisite: high school Algebra II. History of computers, hardware components, operating systems, application software, data communication.
3.000 Credit hours

$ awk '/CSC/{split($0,a,/ - /); gsub(/ /,"",a[1])} /[0-9].000/{printf "%s,%s,%d\n",a[1],a[2],$1}' file
CSC1010,COMPUTERS & APPLICATIONS,3

【讨论】:

    【解决方案2】:

    使用 sed:

    sed -n 's/CSC[^-]*-[ ]*\([^\.]*\).*\([0-9][0-9]*\)\.000[ ]*Credit.*/\1,\2/p' input
    

    【讨论】:

      【解决方案3】:

      @Powdercake,是的,很接近。只需将{print substr(","$1,1,2)} 更改为{print $1+0} 以强制$1 变为(默认)数字格式(并省略@John Zwinck 提到的管道和猫)

      【讨论】:

        【解决方案4】:
        awk '{print $1$2","$4,$5,$6","$(NF-2)}' RS= course_list
        

        说明:

        NF 是一个存储字段数量的内部变量。 $NF 保存最后一个字段的值。由于 OP 想要捕获位于 NF-2 位置的课程时间,因此我们将其打印出来。

        【讨论】:

        • 我的参数RS=被遗漏了,不是吗?
        • 将学时数转换为整数也被忽略了,当课程标题不是 3 个单词时它会失败,而当课程中的不仅仅是这 3 行时它会失败文件。我假设所有这些都是 OP 实际输入的情况,否则编写脚本毫无意义。
        最近更新 更多