【问题标题】:save multiple matches in a list (grep or awk)在列表中保存多个匹配项(grep 或 awk)
【发布时间】:2019-04-07 10:25:12
【问题描述】:

我有一个看起来像这样的文件:

# a mess of text
Hello. Student Joe Deere has
id number 1. Over.
# some more messy text
Hello. Student Steve Michael Smith has
id number 2. Over.
# etc.

我想将(Joe Deere, 1)(Steve Michael Smith, 2) 等对记录到一个列表中(或两个具有相同顺序的单独列表)。也就是说,我需要遍历这些对并使用名称和 ID 做一些事情。

(名称和 ID 在不同的行上,但按以下顺序排列:name1id1name2id2 等在文本中)。我可以用

提取感兴趣的线

VAR=$(awk '/Student/,/Over/' filename.txt)

我想我知道如何用grep 提取名称和ID,但它会给我一个大块的结果

`Joe Deere 1 Steve Michael Smith 2 ...`

(甚至可能在名称和 ID 之间使用分隔符)。在这一点上,我不确定如何继续进行,而且无论如何这都不是正确的方法。

我确信awk 中有一个可以满足我需要的单行代码。可能性是无限的,文档是巨大的。

有什么建议吗?

【问题讨论】:

    标签: text awk grep string-matching


    【解决方案1】:
    $ cat tst.awk
    /^id number/ {
        gsub(/^([^ ]+ ){2}| [^ ]+$/,"",prev)
        printf "(%s, %d)\n", prev, $3
    }
    { prev = $0 }
    
    $ awk -f tst.awk file
    (Joe Deere, 1)
    (Steve Michael Smith, 2)
    

    【讨论】:

    • @Ed Morton 好吧,我需要一点时间才能弄清楚这是在做什么!但至少我得到了同样的结果。我还有一些工作要做。如果我使用VAR=$(awk -f tst.awk file) 存储结果,则echo $VAR 返回(Joe Deere, 1) (Steve Smith , 2)(似乎行尾被转换为空格)。然后使用this other pose 我应该能够解决问题。
    • 您需要尽快了解如何在 shell 中引用,因为了解不正确引用的含义至关重要。你想要echo "$VAR",而不是echo $VAR。前者将"$VAR" 的内容作为一个参数传递给echo,而后者则在每个空格处切分$VAR 的内容,对它们进行通配符和文件名扩展,然后将结果传递给一个“单词”是时候回声了。一个巨大的差异。始终引用 shell 变量,除非您有特定的理由不完全理解所有含义。顺便说一句,不要对未导出的变量名使用全部大写。
    【解决方案2】:

    您也可以尝试一下吗?

    awk '
    /id number/{
      sub(/\./,"",$3)
      print val", "$3
      val=""
      next
    }
    {
      gsub(/Hello\. Student | has.*/,"")
      val=$0
    }
    '  Input_file
    

    【讨论】:

    • 再一次,我需要一些时间来解读您的解决方案的作用。我观察到输出没有捕获全名:一些名字是名字+姓氏,另一些是拳头名字+中间名+姓氏。您的解决方案缺少中间名“Michael”......如上所述,我仍然需要将结果转换为数组。不过谢谢!
    • @Antoine,我从上面的代码中得到Joe Deere, 1 Steve Michael Smith, 2 ,请说明它在哪里不起作用?
    • 对不起!你是对的(我正在使用错误的文件进行测试,一个没有中间名“Michael”的文件,所以我认为你的代码没有捕获它)。我得到了和你一样的结果。
    • @Antoine,请始终尝试通过投票来鼓励帮助您的人,并尝试从所有答案中选择正确答案。
    • @Antoine 您可以随时就您不理解的任何问题提出问题。最后,我们不会使用通用语言结构来记录每一个微小的脚本,但我们通常不会;不介意为那些花一点精力研究结构本身并且需要更多帮助来拼凑它的人回答问题在一起。
    【解决方案3】:
    grep -oP 'Hello. Student \K.+(?= has)|id number \K\d+' file | paste - -
    

    【讨论】:

    • 我的 grep 版本不支持-P...不过,我会通过尝试理解您的代码的作用来学习一些东西!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多