0

I have an output of an analysis and I would like to grep a keyword "X" -which always appears- every time a phrase "Y" occurs. The keyword "X" appears many times but I would like to get only the subsequent after "Y".

For example, I would like to get the subsequent Folder name every time Iter = 10 occurs, i.e. F1, F4.

Iter   = 10
Folder = F1

Iter   = 5
Folder = F2

Iter   = 6
Folder = F3

Iter   = 10
Folder = F4

Any ideas?

Hexdump -c output of file (as requested by @Inian):

0000000   I   t   e   r               =       1   0  \n   F   o   l   d
0000010   e   r       =       F   1  \n  \n   I   t   e   r            
0000020   =       5  \n   F   o   l   d   e   r       =       F   2  \n
0000030  \n   I   t   e   r               =       6  \n   F   o   l   d
0000040   e   r       =       F   3  \n  \n   I   t   e   r            
0000050   =       1   0  \n   F   o   l   d   e   r       =       F   4
0000060  \n                                                            
0000061
ares
  • 121
  • 1
  • 6
  • 1
    So you made any efforts for yourself? Has it needs to be with `grep`? Can `Awk` be used? – Inian Jan 30 '18 at 05:05
  • 2
    Possible duplicate of [Printing with sed or awk a line following a matching pattern](https://stackoverflow.com/questions/17908555/printing-with-sed-or-awk-a-line-following-a-matching-pattern) – Sundeep Jan 30 '18 at 05:10

3 Answers3

3

You could use awk for this requirement. It works on a /pattern/{action} based rule on each line of the input file. So in our case we first match the string Iter = 10 and enable a flag so that on the next match of the string starting with Folder, we extract the last space de-limited column, which in awk is represented by $NF and we reset the flag for subsequent matches.

awk '/\<Iter   = 10\>/{flag=1; next} flag && /^Folder/{print $NF; flag=0;}' file

or without the <> try

awk '/Iter   = 10/{flag=1; next} flag && /^Folder/{print $NF; flag=0;}' file
Inian
  • 80,270
  • 14
  • 142
  • 161
  • Thanks! That solved it, now it works. Can you explain the difference? – ares Jan 31 '18 at 04:52
  • @alex: That is used to match the entire pattern, meaning that there cannot be any more characters other than `Iter = 10` in that line – Inian Jan 31 '18 at 04:56
  • How do I modify this when I need to search using a variable ? I tried something like var="Iter=10" ; awk -v var_name="$var" '/var_name/{flag=1; next} flag && /^Folder/{print $NF; flag=0;}' file . This doesnt work for me – spooja__ Jun 12 '21 at 22:31
  • 1
    @spooja__: See [How to match a pattern given in a variable in awk?](https://stackoverflow.com/q/39384283/5291015) – Inian Jun 13 '21 at 04:07
  • @Inian Thanks ! I went through it more carefully and I think I could figure it out now . This worked for me : var2=`awk -v var_name="$var" '$0~var_name file {flag=1; next} flag && /^Folder/{print $NF; flag=0;}' file` – spooja__ Jun 13 '21 at 09:53
2

You could also you grep:

$ grep -A 1 Iter.*10 file | grep Folder | grep -o "[^ ]*$"
F1
F4

Explained:

  • grep -A 1 Iter.*10 file search for desired pattern and get some trailing context (-A 1, just one line)
  • grep Folder next search for keyword Folder
  • grep -o "[^ ]*$" get the last part of previous output

If there is noise between Iter and Folder lines you could remove that with grep "\(Iter.*10\|Folder\)" file first.

Above expects for Iter line to appear before Folder line. If that is not the case, awk is the cure. For example, data (line orders vary, there is noise):

Folder = F1
Foo    = bar
Iter   = 10

Iter   = 5
Foo    = bar
Folder = F2

$ awk -v RS="" -F"\n" '                        # record separated by empty line
/Iter/ && / 10$/ {                             # look for record with Iter 10
    for(i=1;i<=NF;i++)                         # iterate all fields (lines within record)
        if(split($i,a," *") && a[1]=="Folder") # split Folder line to components
            print a[3]                         # output value
}
' file
F1
James Brown
  • 36,089
  • 7
  • 43
  • 59
  • Thanks! I'll keep a note for this. There is noise, so awk is the cure as Inian mentioned. Works just fine! – ares Jan 31 '18 at 04:55
0

grep is simply regrex search.

For, doing more complex operation, you can use awk.

E.g.

awk '/Iter = 10/ { getline; print $0 }' /path/to/file

where /path/to/file is the file containing your text to be searched

EDIT: Just after posting my answer I read Inian's answer and it is more elaborate and accurate.

tryingToLearn
  • 10,691
  • 12
  • 80
  • 114
  • This is just to get the next line, I need it to search on file after the occurrence of 'Iter = 10' for Folder, where Folder can be anywhere. – ares Jan 30 '18 at 05:20
  • yes. as I mentioned, Inian's answer is more elaborate. I just showed an example way to do it. – tryingToLearn Jan 30 '18 at 05:20