分离脚本文件中的命令?

分离脚本文件中的命令?

我有一个作业,在一个脚本文件中运行一系列 (n)awk 命令。这个脚本文件的关键是过滤掉此处原始文本文件中的某些行和记录,称为学生

Frank       Smith       Engineering  Senior     C
John        Doe         Marketing    Junior     B
Nancy       Jones       Engineering  Junior     A
Betty       Anderson    Nursing      Sophomore  B   
Bob         Johnson     History      Freshman   B   
James       Smith       Economics    Senior     A

我的脚本文件中有这些 awk 命令测试脚本.脚本

{print $2, $1, $3, $4, $5}

/A$/ {print $1, $2} 

/!A$/ {print $1, $2}

截至目前,当我跑步时nawk -f testscript.script students

对于输出的前几行我得到:

Smith Frank Engineering Senior C
Doe John Marketing Junior B
Jones Nancy Engineering Junior A
Nancy Jones 
Anderson Betty Nursing Sophomore B
Johnson Bob History Freshman B
Smith James Economics Senior A
James Smith

如您所见,第二条命令与第一条命令融合在一起,而不是像所希望的那样分开。

这就引出了我的问题:如何分离 shell 脚本中的命令,以便每个新命令都有与其他命令独立的输出?

答案1

它运行完美,正如预期。

您的命令可以简单地重写为:

awk '{print $2, $1, $3, $4, $5}; /A$/ {print $1, $2}; /!A$/ {print $1, $2}' students

它由3个表达式组成awk

  1. {print $2, $1, $3, $4, $5}

  2. /A$/ {print $1, $2}

  3. /!A$/ {print $1, $2}

所有 3 个表达式都将应用于所有记录。

  • 第一个是相应地重新排列字段

  • 如果记录以A( /A$/) 结尾,则第二个匹配,如果是这样,则打印第一个和第二个字段

  • 如果记录以 结尾!A,则第三个匹配,如果是这样,则打印第一个和第二个

  • 由于前两条记录不满足表达式2的条件,因此按照表达式1打印字段。记录号4和5也是如此

  • 只有记录 3 和 6 符合第二个表达式的条件,即以结束,A因此此条件的操作(即打印前两个字段)在执行表达式 1 之后立即执行,即打印重新排列的字段。因此,对记录 3 和 6 应用了两个操作。我想这就是让你绊倒的原因。

  • 没有任何记录符合表达式 3 的条件,即以 结尾!A,也许您想使用条件作为!/A$/即不以 结尾的记录A(并应用所需的操作)。

答案2

您可能更愿意编写一个foo.sh包含三个 awk 命令的 shell 脚本(比如说),而不是包含三个块的单个 awk 脚本:

#!/bin/sh

awk '{print $2, $1, $3, $4, $5}' "$1"
awk '/A$/ {print $1, $2}' "$1"
awk '/!A$/ {print $1, $2}' "$1"

然后下面应该会给出期望的结果:

sh foo.sh students

(您也可以先执行chmod +x foo.sh,然后运行./foo.sh students。)

答案3

引起我注意的首先两个问题:

  1. 您可能想说!/A$/不是,/!A$/因为我想您不想匹配以文字结尾的行,!A但不以文字结尾的行A
  2. 我不知道这是由于您在此处发布示例的方式,还是您的初始数据集中存在这种情况,但有些行包含尾随空格。例如,尝试查看哪些行匹配/B$/以了解我的意思。幸运的是,没有以结尾的行A有尾随空格,因此您的表达式/A$/仍然有效,但它必须被视为脆弱的,因此$5=="A"在任何情况下都应该是首选。

对于你的主要问题,如何“分离”每行的输出,我认为最简单的方法是使用文件重定向。即

{print $2, $1, $3, $4, $5 >"students-reorderd-columns"}
$5=="A"{print $1, $2 >"a-students"}
$5!="A"{print $1, $2 >"non-a-students"}

但是如果您确实需要将其发送到标准输出并希望避免使用cat students-reorderd-columns a-students non-a-students临时文件,您可以研究sprint并收集变量中的输出并将它们打印在一个END块中(这对读者来说应该是一个很好的练习)。

相关内容