【问题标题】:Conditional match when comparing fields in multiple files using AWK使用 AWK 比较多个文件中的字段时的条件匹配
【发布时间】:2022-01-08 19:54:33
【问题描述】:

我想了解在 AIX 6.x 平台上比较 AWK 中不同文件的多个字段时如何/是否可以包含某些条件。以下是我正在尝试做的事情:

Employee.txt (last column is the **status**)
1|canoeing|Sam|Smith|Seatle|X
2|jogging|Barry|Jones|Seatle|
3|football|Garry|Brown|Houston|
4|jogging|George|Bla|LA|X
5|basketballCeline|Wood|Atlanta|
6|tennis|Jody|Ford|Chicago|

Car.txt (last column is **availability**)
100|football|red|1|Y
110|tennis|green|9|N
120|hockey|yellow|2|N
130|football|yellow|6|N
140|jogging|red|8|Y
150|canoeing|white|0|
    
awk -F"|" '
NR == FNR {
   empcar[$3]
   next
}
{
   print > ($1 in empcar ? "match.txt" : "no_match.txt")
}' Car.txt Employee.txt

我喜欢在打印匹配的记录之前检查员工状态是否为 Active(没有 X)和汽车可用性 (Y) 是否相同。这可行吗?

非常感谢, 乔治

【问题讨论】:

  • car.txt 中的第三列是员工编号(employee.txt 的第一列)吗?您想打印来自employee.txt 的全部记录吗?加入两个文件中的记录?还是只是员工编号?
  • 如果您显示所需的输出会有所帮助。在此示例数据中,我没有看到任何拥有可用汽车的在职员工。
  • Car.txt的第三列是Employee.txt的员工编号。所需的输出是两个文件中记录的组合。谢谢

标签: unix awk aix


【解决方案1】:

您可以通过以下方式检查两个文件中的其他条件:

awk -F"|" '
NR==FNR {
   if ($NF == "Y")
      empcar[$(NF-1)]
   next
}
{
   print > ($NF != "X" && $1 in empcar ? "match.txt" : "no_match.txt")
}' Car.txt Employee.txt

【讨论】:

  • 上面的代码有效,但我试图匹配 2 列。假设我在 Employee.txt 和 Car.txt 中添加了另一列($2),名为 sport 并尝试了以下操作但没有成功: bash-4.3$ cat Employee1.txt 1|canoeing|Sam|Smith|Seatle|X 2|jogging|Barry|琼斯|西雅图| 3|足球|加里|布朗|休斯顿| 4|慢跑|乔治|布拉|洛杉矶|X 5|篮球赛琳|伍德|亚特兰大| 6|网球|乔迪|福特|芝加哥| bash-4.3$ cat Car1.txt 100|足球|红色|1|Y 110|网球|绿色|9|N 120|曲棍球|黄色|2|N 130|足球|黄色|6|N 140|慢跑|红色| 8|Y 150|划独木舟|白色|0|
  • 以下 AWK 命令无法匹配 Car.1.txt 和 Employee1.txt 中员工编号和运动字段的组合。 bash-4.3$ awk -F"|" ' NR==FNR { if ($NF == "Y") car[$4,$2]=$0; next } { print > ($NF != "X" && ($1,$2) in car ? "match.txt" : "no_match.txt") }' Car1.txt Employee1.txt no_match.txt 的内容是与 Employee1.txt 相同,但不正确。
  • 如何用格式化示例更新我的问题?我以为我只能添加cmets。谢谢
  • 以下 AWK 命令无法匹配 Car.txt 和 Employee.txt 中员工编号和运动字段的组合。 awk -F"|" ' NR==FNR { if ($NF == "Y") car[$4,$2]=$0; next } { print > ($NF != "X" && ($1,$2) in car ? "match.txt" : "no_match.txt") }' Car.txt Employee.txt no_match.txt 的内容是与 Employee.txt 相同,但不正确。
  • 问题只是说I like to check if the employee status is Active (no X) and the same for car availability (Y) before printing the matched record,这就是我在回答中所做的。请更新要求并显示您的预期输出。
【解决方案2】:

使用您展示的示例,请尝试关注awk 代码。

awk '
BEGIN{ FS=OFS="|" }
FNR==NR{
  arr[$1]=$NF
  arr1[$1]=$0
  next
}
arr[$3]!="X" && $NF=="Y"{
  print arr1[$3] > ("match.txt")
  arr2[$3]
}
END{
  for(i in arr1){
    if(!(i in arr2)){
      print arr1[i] > ("no_match.txt")
    }
  }
}
' Employee.txt car.txt

说明:为上述代码添加详细说明。

awk '                                      ##Starting awk program from here.
BEGIN{ FS=OFS="|" }                        ##Setting FS and OFS to | in BEGIN section.
FNR==NR{                                   ##Checking condition FNR==NR which will be TRUE when Employee.txt is being read.
  arr[$1]=$NF                              ##Creating array arr with index of $1 and value of last field.
  arr1[$1]=$0                              ##Creating array arr1 with index of $1 and value of current line.
  next                                     ##next will skip all further statements from here.
}
arr[$3]!="X" && $NF=="Y"{                  ##Checking condition if arr array with index of 3rd column value is not X and last field is Y then do following.
  print arr1[$3] > ("match.txt")           ##Printing respective entry from Employee.txt into match.txt file here.
  arr2[$3]                                 ##Creating an entry in arr2 with index of $3 here.
}
END{                                       ##Starting END block of this awk program from here.
  for(i in arr1){                          ##Traversing through arr1 here.
    if(!(i in arr2)){                      ##Checking if i(current item index) is NOT present in arr2 then do following.
      print arr1[i] > ("no_match.txt")     ##Printing respective value to no_match.txt file.
    }
  }
}
' Employee.txt car.txt                     ##Mentioning Input_file names here.

【讨论】:

  • 请使用更具描述性的数组名称。 arrarr1 无助于证明这一点。
  • @glennjackman,感谢格伦的反馈。平时都是这样,这次错过了,会改的,谢谢。
  • 运行这段代码没有任何输出。不过感谢您的努力。
【解决方案3】:

这个怎么样:

awk -F'|' 'FNR==NR { empcar[$3]; next } $1 in empcar && $5 != "X"' cars emps

输出:

2|Barry|Jones|Seatle|
6|Jody|Ford|Chicago|

【讨论】:

  • 我得到以下输出:1|Sam|Smith|Seatle 2|Barry|Jones|Seatle 6|Jody|Ford|Chicago 感谢您的努力。
  • 这听起来像是输入文件的格式问题。员工文件是否有尾随空格?
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2014-12-25
  • 1970-01-01
  • 1970-01-01
  • 2022-01-01
  • 2016-07-30
  • 1970-01-01
相关资源
最近更新 更多