按照模式提取字符串 (grep)

Extract string following pattern (grep)

我正在努力学习如何使用 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  
numpy 1.21.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是版本

你的问题可以用两种不同的方式来理解:

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

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

File1.txt:

test1
test2
something_else

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

解决方案:

grep "test" File1.txt

=> 不需要循环,因为 grep 能够找到所有结果 其中 找到一个模式。

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

循环

如果您有 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 ( == "-") {
        split(, fields, "=")
        print fields[1], fields[2]
      } else p=0 }' file.yaml

使用 awk:

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

Ed Morton 的代码: