【问题标题】:Find patterns of a file in another file and print out a corresponding field of the latter maintaining the order在另一个文件中查找一个文件的模式,并打印出后者的相应字段,保持顺序
【发布时间】:2016-01-28 03:22:22
【问题描述】:

我已经尝试了一段时间来解决这个问题,但我检查了很多帖子(例如这里Print lines in one file matching patterns in another file 或这里awk search for a field in another file),但没有真正找到我想要的东西。我需要使用 sed、grep、awk 等 bash 工具(没有 python、R、...)的解决方案

我有两个文件(比那些大得多):

文件1:

   2   891299  0.50923964E-02     1248   4.713       1349.08
   3   245857  0.57915542E-02     1335   4.671       1369.65

文件2:

   278    2645  2334659  0.75142      0.53123
   279    2643   245857  0.80439      0.56868
   500    1341   830677  0.74922      0.52958
   501    1339   882791  0.87685      0.61980
   502    1337   891299  0.63224      0.44680

在此示例中,我想在 file2 的第 3 列中找到 file1 的第 2 列中的模式,并打印后者的第 1 列,用于 file1 的所有行并保持 file1 给出的顺序。

一个可能的解决方案(我知道不是没有错误)是以下令人无法接受的缓慢 bash 循环:

for i in `awk '{print $2}' file1` ; do grep " $i " file2 | awk '{print $1}' ; done

打印到屏幕上:

502

279

请注意“简单”的解决方案,例如:

awk 'NR==FNR{pats[$2]; next} $3 in pats' file1 file2

不合适,因为打印顺序是由 file2 而不是由 file1 给出的(即它先打印到屏幕 279,然后是 502)。

非常感谢您的帮助。

【问题讨论】:

    标签: bash awk grep pattern-matching


    【解决方案1】:

    你可以反转要在awk中处理的文件,得到正确的输出:

    awk 'NR==FNR{pats[$3]=$1; next} $2 in pats{print pats[$2]}' file2 file1
    502
    279
    

    【讨论】:

    • 非常感谢您的回答。我应该提到,排序可以是任何(随机),并且不能通过 file1 的简单反转来调整,就像在这个简单的例子中一样,它可以工作。 File1 通常由数千行组成,file2 也是如此。当然,这并不意味着不能在匹配过程中以某种我没有发现的巧妙方式使用排序。再次感谢。
    • 没有理由进行任何排序。您的慢 BASH 脚本还根据它们在 file1 中的外观维护列顺序,而这个 awk 也在做同样的事情。只需在更大的文件上试一试,然后看看。
    • 是的,你是对的,非常感谢,这解决了我的问题!
    猜你喜欢
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多