Соответствуйте строке и распечатайте строки от того же блока, соответствующего другой строке

У меня есть большой файл больше чем с 5 000 строк в следующем формате

Ниже отрывка показывает два блока файла.

string name    : abcd

    used :metric
    test :ok

{


 fun: add

 fun: sub

 fun: mul

 fun: div

}   


string name    : degh

    used: non -metric
    test: good

{


 fun: per

 fun: div

 fun: add

 fun: mul


}   

То, в чем я нуждаюсь, должно искать string name (например: abcd), и затем распечатайте значения после fun : от этого string nameблок

Я хотел бы следующий вывод:

abcd    add
abcd    sub
abcd    mul
abcd    div
degh    per
degh    div
degh    add
degh    mul

Каков был бы надлежащий способ решить эту проблему?

-1
задан 19 March 2018 в 14:04

3 ответа

#!/bin/bash

RE_NAME='^ *string name *:' # regex for the 'name' line
RE_FUNSTART='^ *[{] * 

Bash может быть немного медленным для больших файлов. Если это слишком медленно для Вас, Вы могли бы портировать код на, например, Perl или Python.

# regex for the start of the 'fun' block RE_FUNEND='^ *[}] *

Bash может быть немного медленным для больших файлов. Если это слишком медленно для Вас, Вы могли бы портировать код на, например, Perl или Python.

# regex for end of 'fun' block RE_FUN='^ *fun:' # regex for 'fun' line while read line; do if [[ $line =~ $RE_NAME ]]; then name="${line##*: }" echo elif [[ $line =~ $RE_FUNSTART ]]; then fun='1' elif [[ $line =~ $RE_FUNEND ]]; then fun='' elif [[ ($line =~ $RE_FUN) && (-n $fun) ]]; then # match 'fun' lines only inside 'fun' block echo "$name ${line##*: }" fi done < your_big_file

Bash может быть немного медленным для больших файлов. Если это слишком медленно для Вас, Вы могли бы портировать код на, например, Perl или Python.

0
ответ дан 6 October 2019 в 18:41

Другой подход с awk:

 awk '{ if ($1 == "string") name = $4; else if ($1 == "fun:") print name " " $2; }' your_file

Предположение, которые" string name" и" :" разделяются пространством и" fun", всегда сопровождается" :" без пространства.

0
ответ дан 6 October 2019 в 18:41

Один из способов приблизиться к нему с жемчугом:

$ perl -lane '$hold=$F[3] if $_ =~ "^string name.*";print "$hold $F[1]" if $F[0] eq "fun:"' bigfile.txt                                                                
abcd add
abcd sub
abcd mul
abcd div
degh per
degh div
degh add
degh mul
1
ответ дан 6 October 2019 в 18:41

Другие вопросы по тегам:

Похожие вопросы: