Romain Bosq
Romain Bosq

Reputation: 51

Extract string following pattern (grep)

I am trying to learn how to use grep. I have a file that list my python packages as follow:

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

I am only interested what comes after "dependancies". I am trying, using bash grep/sed/awk whatever basic linux tool, to iterate in all those lines, to save in one variable the python package and in another variable the version (I dont care about what is after the last =) and to call a function.

Example for the first line:

$ > echo $1 $2
numpy 1.21.1

Thans you for your help

Upvotes: 0

Views: 329

Answers (4)

Alireza
Alireza

Reputation: 2123

You can use this:

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

Where test.txt is:

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

And $A is the package name and $B is version

Upvotes: 1

Carlos Pascual
Carlos Pascual

Reputation: 1126

using 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's code: https://stackoverflow.com/a/66188243/14259465

Upvotes: 1

tripleee
tripleee

Reputation: 189936

If you have YAML input, the proper soulution is to use a YAML tool like yq.

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

If you are unable to install yq, maybe try Awk; but understand that this is brittle, and makes assumptions about your YAML formatting.

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

Upvotes: 1

Dominique
Dominique

Reputation: 17565

Your question can be understood in two different ways:

  • I would like grep in order to avoid needing a loop.
  • I know I need to write a loop, but I don't know how to use grep in a loop.

It is correct that grep can avoid loops, like in this example:

File1.txt:

test1
test2
something_else

Mission: loop through the file and give every entry, starting with "test".

Solution:

grep "test" File1.txt

=> no loop needed, because grep is capable of finding all results where a pattern is found.

However, I don't think grep has an option stating "Give all results once a pattern is found.", so here you cannot avoid writing a loop using grep.

Upvotes: 0

Related Questions