【问题标题】:Add rows from another file when condition is true当条件为真时从另一个文件添加行
【发布时间】:2020-11-09 17:12:36
【问题描述】:

继续链接Print rows with condition on field data中的问题

我有另一个包含数据的文件 2

cell   input  out  type   fun  level
CLK    C       Z    seq   Cq   1      
DFk    C,Cp    Q    seq   IQ   1
DFR    D,C     Qn   seq   IN   1
SKN    SE,Q    Qp   seq   Iq   1

下面的代码是获取级别总和为 7 并打印行。

awk '
function rnd(max) {        
   return int(rand()*max-1)+2
}
BEGIN {
   srand()                
}
NR == 1 {                  
   print                   
   next
}
{
   rec[NR] = $0           
   num[NR] = $NF           
}
END {
   while(1) {             
      r = rnd(NR)          
      if (!seen[r]++)      
         s += num[r]      

      if (s == 7)         
         break
      else if (s > 7) {   
         delete seen
         s = 0
         continue
      }
   }
   for (j in seen)         
      print rec[j]
} ' file1

上面的代码每次执行时只打印一组输出(level sum 7 true)。

但现在我想打印两组数据,当我执行一次代码时,当 level sum = 7 为真时,我想在新行中插入来自 file2 的行。

输出结果

cell   input     out    type      fun            level
AI20   A1,A2      Z     comb    ((A1A2))           2
INV    I1         ZN    comb    (!I1)              1  
BUF  A1,A2,A3,B1  Z     comb    (!(((A1A2)A3)B1))  4
CLK    C          Z     seq      Cq                1
XOR    A1,A2,B1   Z     comb    (((A1A2)B1)        3
IAD    A1,A2,A3   Z     comb    (!((A1A2)A3))      3
INV    I1         ZN    comb    (!I1)              1

在输出中,我们可以看到CLK C Z seq Cq 1 行是从 file2 插入的,而 file1 的级别总和为 7。

为了得到这个输出,我将上面的代码修改为

awk '
function rnd(max) {        
   return int(rand()*max-1)+2
}
BEGIN {
   srand()                
}
NR == 1 {                  
   print                   
   next
}
{
   rec[NR] = $0           
   num[NR] = $NF           
}
END {
   for (( i=1; i<3;i++)) 
     do  
         
      r = rnd(NR)          
      if (!seen[r]++)      
         s += num[r]      

      if (s == 7)         
         for line in $file2
           do
             awk '{ $0 }'
           done
     done

      else if (s > 7) {   
         delete seen
         s = 0
         continue
      }
   
   for (j in seen)         
      print rec[j]
} ' file1

但是从 file2 打印行时出现错误。

【问题讨论】:

  • 那么在您的预期输出中,您有 7 个数据行?是这样的:file1 的 3 行(sum=7)+ file2 的 1 行 + 文件的 3 行(sum=7)?
  • 是的……非常好。但不是来自 file1 的 3 行,它应该包含来自 file1 的行,导致总和 = 7,因此行数可以是任何取决于级别的行。由于我想要来自 file1 的两组输出,这就是为什么上面的代码是 file1 的 3 行(sum=7)+ file2 的 1 行 + 文件的 3 行(sum=7)
  • 好的理解这部分但是应该从file2中选择哪条记录?
  • 当我们得到 sum 为 7 时,从文件 2 中打印一行。
  • 假设我想要 3 组数据在单次执行中得到总和 7。那么我将有 rows from file1 sum=7 + first row from file2 + rows from file1 sum =7 + second row from file2 + rows from file1 sum =7

标签: awk


【解决方案1】:

您可以使用这个增强的 awk 脚本:

cat rnd.awk

function rnd(max) {           # generate a randon number between 2 and max
   return int(rand()*max-1)+2
}
function rndsum() {
   while(1) {                 # infinite loop
      r = rnd(NR)             # generate a randomm number between 2 and NR
      if (!seen[r]++)         # populate seen array with this random number
         s += num[r]          # get aggregate sum from num array

      if (s == sum)           # if sum then break the loop
         break
      else if (s > sum) {     # if s > sum then restart the loop
         delete seen
         s = 0
         continue
      }
   }
   for (j in seen)            # for each val in seen print rec array
      print rec[j]
   delete seen
   s = 0
}
BEGIN {
   srand()                    # seed random generation
}
NR == 1 {                     # for header row
   print                      # print header record
   next
}
FNR == NR {                   # while processing file1
   rec[NR] = $0               # save each record in rec array with NR as key 
   num[NR] = $NF              # save last column in num array with NR as key
   next
}
FNR > 1 {
   rec2[++n] = $0             # records in file2 being saved in rec2
}
END {
   rc = rc > n ? n : rc       # allow rc to be max of row count in file2
   for (i=1; i<=rc; ++i) {    # for 1..rc
      rndsum()               # print random rows from file1
      print rec2[i]           # print a row from file2
   }
   rndsum()                  #  print random rows from file1
}

现在将其用作:

awk -v sum=7 -v rc=2 -f rnd.awk file1 file2 | column -t

cell  input        out  type  fun                level
IA2   A1,A2,A3     Z    comb  ((!A1A2)A3)        3
BUF   A1,A2,A3,B1  Z    comb  (!(((A1A2)A3)B1))  4
CLK   C            Z    seq   Cq                 1
IA2   A1,A2,A3     Z    comb  ((!A1A2)A3)        3
IAD   A1,A2,A3     Z    comb  (!((A1A2)A3))      3
INV   I1           ZN   comb  (!I1)              1
DFk   C,Cp         Q    seq   IQ                 1
XOR   A1,A2,B1     Z    comb  (((A1A2)B1)        3
IAD   A1,A2,A3     Z    comb  (!((A1A2)A3))      3
INV   I1           ZN   comb  (!I1)              1

又一次:

awk -v sum=7 -v rc=1 -f rnd.awk file1 file2 | column -t

cell  input        out  type  fun                level
IAD   A1,A2,A3     Z    comb  (!((A1A2)A3))      3
BUF   A1,A2,A3,B1  Z    comb  (!(((A1A2)A3)B1))  4
CLK   C            Z    seq   Cq                 1
XOR   A1,A2,B1     Z    comb  (((A1A2)B1)        3
BUF   A1,A2,A3,B1  Z    comb  (!(((A1A2)A3)B1))  4

【讨论】:

  • 所以在输出中.. 在第一个输出中,awk -v rc=2 -f rc=2 显示来自 file2 的两行。但在第二个输出中也是 rc=2 但只显示 file2 中的一行??
  • 先生,我可以让它更具交互性,即用户定义。这样用户为 sum s 和 rc 提供输入值?我尝试使用read -p " enter sum :" sum 并将总和要求替换为s==$sumrcawk -v rc=$number -f rnd.awk file1 file2 类似,但这不起作用。
  • 检查我更新的答案。你可以这样称呼它:awk -v sum=$sum -v rc=$rc -f rnd.awk file1 file2 | column -t
  • 是的,先生,它奏效了。先生,我对另一个问题有疑问,我已经发布了“引用字段并为该字段分配逻辑”你能帮我解决这个问题吗?@anubhava
猜你喜欢
  • 1970-01-01
  • 2021-02-07
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-10
相关资源
最近更新 更多