【问题标题】:Extract string following pattern (grep)按照模式提取字符串(grep)
【发布时间】:2021-10-12 23:51:40
【问题描述】:

我正在尝试学习如何使用 grep。 我有一个文件列出了我的 python 包如下:

channels:
  - conda-forge
  - defaults
dependencies:
  - numpy=1.21.1=py39h6635163_0
  - pyinstaller=4.2=py39h4dafc3f_1
  - ...

我只对“依赖”之后的内容感兴趣。 我正在尝试使用 bash grep/sed/awk 任何基本的 linux 工具来迭代所有这些行,将 python 包保存在一个变量中,并将版本保存在另一个变量中(我不关心最后一个 = 之后的内容)和调用函数。

第一行示例:

$ > echo $1 $2
numpy 1.21.1

感谢您的帮助

【问题讨论】:

  • 别偷懒,提供循环并至少声明函数
  • - stackoverflow.com 中的类似问题:“是否有一种简单的 awk/sed 方法可以在 YAML 文件中打印列表?”您可以在哪里使用 awk 获得 Ed Morton 的答案:stackoverflow.com/a/66188243/14259465

标签: awk sed grep


【解决方案1】:

你可以用这个:

grep -oP "\w+=[\d.]+" test.txt | while IFS="=" read -r P V; do
    export A=$P
    export B=$V
done

test.txt 在哪里:

channels:
  - conda-forge
  - defaults
dependencies:
  - numpy=1.21.1=py39h6635163_0
  - pyinstaller=4.2=py39h4dafc3f_1
  - ...

$A 是包名,$B 是版本

【讨论】:

  • 不要在子进程中的每个值上单独调用cut,而是使用while IFS='=' read -r A B _; do
  • 可能注意到grep -P是非标准的;但将正则表达式重构为沼泽标准 POSIX 并不难。
  • 编辑了我的答案,谢谢。
【解决方案2】:

您的问题可以通过两种不同的方式来理解:

  • 我想要grep 以避免需要循环。
  • 我知道我需要写一个循环,但我不知道如何在循环中使用grep。

grep 可以避免循环是正确的,就像这个例子:

文件1.txt:

test1
test2
something_else

任务:遍历文件并给出每个条目,以“test”开头。

解决方案:

grep "test" File1.txt

=> 不需要循环,因为grep 能够找到在哪里找到模式的所有结果。

但是,我认为grep 没有选项说明“一旦找到模式后给出所有结果。”,所以在这里你不能避免使用grep 编写循环。

【讨论】:

    【解决方案3】:

    如果您有 YAML 输入,正确的解决方案是使用 YAML 工具,例如 yq。

    yq eval '.dependencies[]' file.yaml |
    while IFS='=' read -r package version _; do
        echo Package: "$package"
        echo Version: "$version"
    done
    

    如果你无法安装yq,不妨试试Awk;但请理解这很脆弱,并且会对您的 YAML 格式做出假设。

    awk '/dependencies:/ { p=1; next }
        p { if ($1 == "-") {
            split($2, fields, "=")
            print fields[1], fields[2]
          } else p=0 }' file.yaml
    

    【讨论】:

      【解决方案4】:

      使用awk:

      awk '$1 == "-"{ if (key == "dependencies:") print $NF; next } {key=$1}' file
      numpy=1.21.1=py39h6635163_0
      pyinstaller=4.2=py39h4dafc3f_1
      ...
      

      Ed Morton 的代码:https://stackoverflow.com/a/66188243/14259465

      【讨论】:

        猜你喜欢
        • 2011-07-02
        • 2016-08-27
        • 2019-03-06
        • 2021-05-23
        • 2023-03-20
        • 2015-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多