简体   繁体   中英

Print multiple-line section between two strings only if this section contains certain keyword using bash?

I have a file named animals which has following entries:

$ cat animals
name: elephant
class: mammal
habitat: India

name: Baltic herring
class: fish
habitat: Baltic sea

name: wolf
class: mammal
habitat: Sweden

name: eagle
class: bird
habitat: USA
$ 

As seen above, this file contains four sections. I would like to print out only those sections which contain string mammal and I would like to do this in bash, ie not use sed or awk . I did it like this:

$ cat animals | while read -r line; do
>   if [[ "$line" =~ ^name ]]; then
>     section="$line"
>     while read -r line2; do
>       if [[ "$line2" =~ ^$ ]]; then
>         break
>       else
>         section+=$'\n'"$line2"
>       fi
>     done
>   echo "$section" | grep -q mamm && echo "$section"$'\n' ; section=
>   fi
> done
name: elephant
class: mammal
habitat: India

name: wolf
class: mammal
habitat: Sweden

$ 

However, is there a more elegant(shorter and not so cumbersome) way to achieve this in bash? Or is this a point where one should look into tools like awk instead?

一个简单的怎么样

grep mammal -C 1 --group-separator="" animals

Yes, you should look into awk. It allows you to do this much more simply:

awk -v RS= -v ORS='\n\n' '/mammal/' file

This unsets the record separator, so that each block is treated as a single record. It then prints each record that matches the pattern "mammal", followed by two newlines, producing the same output as shown in the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM