如何找到部分字符串的匹配项,然后使用awk从引用文件中删除该字符串?

如何找到部分字符串的匹配项,然后使用awk从引用文件中删除该字符串?,awk,ksh,Awk,Ksh,我有一个问题,我一直在试图解决,但一直无法想出如何做到这一点。我有一个参考文件,其中按条形码列出了我库存中的所有设备 参考文件: PTR10001,PRINTER,SN A PTR10002,PRINTER,SN B PTR10003,PRINTER,SN C MON10001,MONITOR,SN A MON10002,MONITOR,SN B MON10003,MONITOR,SN C CPU10001,COMPUTER,SN A CPU10002,COMPUTER,SN B CPU100

我有一个问题,我一直在试图解决,但一直无法想出如何做到这一点。我有一个参考文件,其中按条形码列出了我库存中的所有设备

参考文件:

PTR10001,PRINTER,SN A
PTR10002,PRINTER,SN B
PTR10003,PRINTER,SN C 
MON10001,MONITOR,SN A
MON10002,MONITOR,SN B
MON10003,MONITOR,SN C
CPU10001,COMPUTER,SN A
CPU10002,COMPUTER,SN B
CPU10003,COMPUTER,SN C
我想做的是做一个文件,我只需要把我需要的缩写写在上面。 文件2如下所示:

PTR
CPU
MON
MON
该文件的理想输出将是一个文件,该文件将通过条形码告诉我需要从货架上取下哪些物品。
所需的输出文件:

PTR10001
CPU10001
MON10001
MON10002
如输出中所示,由于我不能有2个相同的条形码,我需要它查看参考文件并找到第一个匹配项。将数字复制到输出文件后,我想从参考文件中删除该数字,这样它就不会重复该数字

我尝试了awk的多次迭代,但未能获得所需的输出。
我得到的最接近的代码如下:

awk -F'/' '{ key = substr($1,1,3) } NR==FNR {id[key]=$1; next} key in id { $1=id[key] } { print }' $file1 $file2 > $file3
我用ksh写这篇文章,我想用awk,因为我认为这是解决这个问题的最佳答案。
感谢您在这方面的帮助。

第一个解决方案:

根据您的详细描述,我认为订单无关紧要,因为您想知道从货架上取下什么。因此,您可以做相反的事情,首先阅读
file2
,数一数物品,然后到书架上拿

awk -F, 'FNR==NR{c[$0]++; next} c[substr($1,1,3)]-->0{print $1}' file2 file1
输出:

PTR10001
MON10001
MON10002
CPU10001

第二种解决方案:

您的
awk
非常接近您想要的,但是您需要在数组中添加第二个维度,并且不要覆盖现有的id。我们将使用一个伪二维数组(顺便说一句,GNU awk有真正的二维数组)来实现这一点,我们在其中存储ID,如
PTR10001、PTR10002、PTR10003
,我们使用
split
检索它们,并将它们从架子上移除

> cat tst.awk
BEGIN { FS="," }

NR==FNR {
    key=substr($1,1,3)
    ids[key] = (ids[key]? ids[key] "," $1: $1) #append new id.
    next
}

$0 in ids {
    split(ids[$0], tmp, ",")
    print(tmp[1])
    ids[$0]=substr(ids[$0],length(tmp[1])+2) #remove from shelf
}
输出

awk -f tst.awk file1 file2
PTR10001
CPU10001
MON10001
MON10002

这里我们保留
file2
的顺序,因为这是基于您尝试过的想法。

请您尝试以下内容,并使用GNU
awk
中显示的示例编写和测试

awk '
FNR==NR{
  iniVal[$0]++
  next
}
{
  counter=substr($0,1,3)
}
counter in iniVal{
  if(++currVal[counter]<=iniVal[counter]){
     print $1
     if(currVal[counter]==iniVal[counter]){ delete iniVal[$0] }
  }
}
' Input_file2  FS="," Input_file1
awk'
FNR==NR{
iniVal[$0]++
下一个
}
{
计数器=子计数器($0,1,3)
}
柜台{

if(++currVal[counter]谢谢。我确实尝试过,效果很好。但是,我选择了下面的单线awk解决方案。我使用了第一个解决方案,因为我总是可以重新排序输出以满足我的需要。我无法使第二个解决方案正常工作。感谢您的帮助。
awk '                                           ##Starting awk program from here.
FNR==NR{                                        ##Checking condition if FNR==NR which is true when Input_file2 is being read.
  iniVal[$0]++                                  ##Creating array iniVal with index of current line with increment of 1 each time it comes here.
  next                                          ##next will skip all further statements from here.
}
{
  counter=substr($0,1,3)                        ##Creating counter variable which has 1st 3 characters of Input_file1 here.
}
counter in iniVal{                              ##Checking if counter is present in iniVal then do following.
  if(++currVal[counter]<=iniVal[counter]){      ##Checking if currValarray with index of counter value is lesser than or equal to iniVal then do following.
     print $1                                   ##Printing 1st field of current line here.
     if(currVal[counter]==iniVal[counter]){     ##Checking if currVal value is equal to iniVal with index of counter here.
       delete iniVal[$0]                        ##If above condition is TRUE then deleting iniVal here.
     }
  }
}
' Input_file2  FS="," Input_file1               ##Mentioning Input_file names here.