【问题标题】:search in one file given patterns from another one在一个文件中搜索给定模式的另一个文件
【发布时间】:2013-12-03 08:05:44
【问题描述】:

我正在为这个问题在 linux shell 中寻找一个紧凑/优雅的解决方案(如果可能的话,ksh)。

给定 2 个文件,都包含具有恒定结构的行,例如:

文件 A

354guitar..06
948banjo...05
123ukulele.04

文件B

354bass....04
948banjo...04

我想以某种方式在文件 A 上循环,并在文件 B 中搜索在位置 4-11 具有相同内容但在位置 12-13 具有不同内容的行。

对于上述情况,我希望文件 B 的第二行作为输出,“banjo...”匹配文件 A 的第二行和 05!=04。

我正在考虑使用 awk,但我自己找不到解决方案:(

谢谢!

【问题讨论】:

    标签: linux shell awk grep ksh


    【解决方案1】:

    用 awk 真的很简单:

    $ awk '{a=substr($0,4,8);b=substr($0,12,2)}NR==FNR{c[a]=b;next}a in c&&c[a]!=b' fileA fileB
    948banjo...04
    

    或者以更易读的格式,您可以将以下内容保存在脚本名称file.awk中

    #!/bin/awk -f
    { # This is executed for every input line (both files)
            a=substr($0,4,8) # put characters 4 through 11 to variable a
            b=substr($0,12,2) # put characters 12 and 13 to variable b
    }
    NR==FNR{  # This is executed only for the first file 
            c[a]=b  # store into map c index a, value b
            next # Go to the next record (remaining commands ignored)
    }
    # The remaining is only executed for the second file (due to the next command)
    (a in c) && (c[a] != b) # if a is an index of the map c, and the value
                            # we previously stored is not the same as the current b value
                            # then print the current line (this is the default acttion)
    

    然后像这样执行:

    awk -f file.awk fileA fileB
    

    【讨论】:

    • 太好了,非常感谢!如果可能的话,最好简要解释一下它的作用......
    • @Pintun 添加了一些解释。如果仍然缺少某些内容,请在此处评论
    【解决方案2】:

    您可以使用像这样的 zsh one-liner:

    for line in `cat fileA`; do grep '^\d\{3\}$line[4,11]' fileB | grep -v '$line[12,14]$'; done
    

    【讨论】:

    • 这也行得通,但写成while read -r -d$'\n' line; do .... ; done < fileA 可能更安全,以防文件不适合命令缓冲区,或者行中有空格。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-25
    相关资源
    最近更新 更多