【问题标题】:file column compare awk (gawk) with refinment文件列比较 awk (gawk) 与细化
【发布时间】:2016-12-08 19:05:44
【问题描述】:

来自我的两个输入文件: (file1.txt)

a   11-23
b   33-39
c   40-45
d   46-58

& (file2.txt)

33-39
40-42
43-47
51-52

我需要匹配 file1 的第二列中的 file2 值(检查中间范围)并希望输出如下:

b   33-39
c   40-42, 43-45
d   46-47, 51-52

请注意,'d 46-47, 51-52' 出现在最后一行,因为 file2 中的 43-47 范围属于 c 和 d。

堆栈溢出用户 karakfa,优雅地建议如下方式:

$ join -j 99 file1 file2 | 
  awk '$2==$3{print $1,$2; next} {split($2,a,"-"); split($3,b,"-")}
   a[1]>=b[1] && a[2]<=b[2] || a[1]<=b[1] && a[2]>=b[2] {print $1,$2",",$3}'

输出如下:

b 33-39
c 40-45, 40-42
d 46-58, 51-52

但是,“c 40-45”和“d 46-58”的整个范围值不是我想要的范围,而且我需要它与 GNU Awk 兼容才能在我的 Windows 机器上运行。

【问题讨论】:

  • 我怀疑awk 最适合这里的工作..
  • 你自己尝试了什么?您是否查看过 awk 文档,是否了解数组的工作原理、如何在数组上创建循环、如何处理多个文件...?

标签: awk


【解决方案1】:

TXR中的解决方案:

@(do
   (defstruct interval nil
     lo hi

     (:postinit (self)
       (unless (< self.lo self.hi)
         (swap self.lo self.hi)))

     (:method print (self stream)
       (put-string `@{self.lo}-@{self.hi}` stream))

     (:method intersects (self other)
       (and (>= self.hi other.lo)
            (<= self.lo other.hi)))

     (:method clip (self other)
       (new interval
            lo (max self.lo other.lo)
            hi (min self.hi other.hi))))

   (defstruct tabentry nil
     label
     interval
     matches

     (:method insert (self other)
       (when self.interval.(intersects other)
         (push self.interval.(clip other) self.matches)))))
@(next "file1.txt")
@(collect :vars (tab))
@label @lo-@hi
@  (bind tab @(new tabentry
                   label label
                   interval (new interval
                                 lo (int-str lo)
                                 hi (int-str hi))))
@(end)
@(next "file2.txt")
@(repeat)
@lo-@hi
@  (do
     (let ((iv (new interval
                    lo (int-str lo)
                    hi (int-str hi))))
       (each ((te tab))
         te.(insert iv))))
@(end)
@(do (each ((te tab))
       (when te.matches
         (put-line `@{te.label} @{(reverse te.matches) ", "}`))))

运行:

$ txr tab-range.txr 
b 33-39
c 40-42, 43-45
d 46-47, 51-52

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 2019-09-08
    • 2018-03-04
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多