Grep line after/before -A/-B substitution in AIX

5,134

Solution 1

I would do it slightly differently. First, run the db2 LIST DB DIRECTORY command and save its output to a text file. That way, you don't need to re-run it multiple times. Then, for each of your target names, pass the name to an awk script that collects the relevant lines:

## Run the db command
tempfile=$(mktemp)
db2 LIST DB DIRECTORY > "$tmpfile"
## I am assuming you will have a loop for the different target names
for name in OLTPF OLTPA; do
  awk -v name="$name" '{
       if(/Database alias/){n=$4; a[n]=$0; i=1}
       if (i<=6 && i>1){ a[n]=a[n]"\n"$0}
       i++;
      }END{if(name in a){print a[name]}}' $tempfile
done

Solution 2

ed may provide a simple way to complete this task.

If we can assume that there is only a single match, then an alternative to your pipeline, using ed and eliminating the unnecessary cat and secondary grep:

ed -s file <<\EOED | awk '/Database name/ {print $4}'
    /Directory entry type.*Indirect/-4,//p
    q
EOED

If there are multiple, non-overlapping matches, ed's global command can be used to mark them:

ed -s file <<\EOED | awk '/Database name/ {print $4}'
    g/Directory entry type.*Indirect/-4,.p
    q
EOED

To demonstrate the case of overlapping matches, assuming we are matching the string foo, and there are matches on lines 7 and 9, and we are pulling the three preceding lines of each match as context, the output would look like this:

line 4      <--- context
line 5      <--- context
line 6      <--- context
line 7 foo  <--- matched
line 6      <--- context      <--- repeated
line 7 foo  <--- context      <--- repeated
line 8      <--- context
line 9 foo  <--- matched
line 10
line 11
Share:
5,134
Nir
Author by

Nir

Updated on September 18, 2022

Comments

  • Nir
    Nir almost 2 years

    I'm using AIX 6.1 which isn't supporting in -B and -A flags:

    grep: Not a recognized flag: B
    

    Lets say I want to run:

    cat file | grep -E -B4 'Directory entry type.*Indirect' | grep "Database name" | awk  '{print $4}'
    

    How can I do this kind of logic in AIX?

    EDIT

    My real code is as follow:

    NAME_EXISTS=`db2 LIST DB DIRECTORY | grep -E -B5 'Directory entry type.*Remote' | grep "Database alias" | awk '{print $4}' | grep -i ${NAME} | wc -l`
    if [ ${NAME_EXISTS} -gt 0 ]; then
        db2 LIST DB DIRECTORY | grep -E -A5 "Database alias.*${NAME}"
    fi
    

    The idea is to find if there is a remote DB named $NAME, if it finds it - show the 5 lines beginning Database alias.*${NAME}. $NAME is unique in Database alias .

    And the db2 LIST DB DIRECTORY output something like this:

     System Database Directory
    
     Number of entries in the directory = 3
    
    Database 1 entry:
    
     Database alias                       = OLTPA
     Database name                        = OLTPA
     Local database directory             = /db2/data
     Database release level               = 10.00
     Comment                              =
     Directory entry type                 = Indirect
     Catalog database partition number    = 0
     Alternate server hostname            =
     Alternate server port number         =
    
    Database 2 entry:
    
     Database alias                       = OLTPF
     Database name                        = OLTP
     Node name                            = OLTPN
     Database release level               = 10.00
     Comment                              =
     Directory entry type                 = Remote
     Catalog database partition number    = -1
     Alternate server hostname            =
     Alternate server port number         =
    
    Database 3 entry:
    
     Database alias                       = ADMIN
     Database name                        = ADMIN
     Local database directory             = /db2/data
     Database release level               = 10.00
     Comment                              =
     Directory entry type                 = Indirect
     Catalog database partition number    = 0
     Alternate server hostname            =
     Alternate server port number         =
    

    For NAME=OLTPF output will be:

     Database alias                       = OLTPF
     Database name                        = OLTP
     Node name                            = OLTPN
     Database release level               = 10.00
     Comment                              =
     Directory entry type                 = Remote
    

    For NAME=OLTPE there will be no output.

    • BitsOfNix
      BitsOfNix over 8 years
    • 123
      123 over 8 years
      Do it all in awk, rarely a reason to use both grep and awk.
    • EightBitTony
      EightBitTony over 8 years
      Can you include some context from the file in question - enough so that we can see if AIX's -p parameter is useful here.
    • terdon
      terdon over 8 years
      Please edit your question and give us an example of your input file. Will Database name always be exactly 4 lines before Directory entry type.*Indirect or can it be anywhere in the preceding 4 lines?
    • Nir
      Nir over 8 years
      @terdon Yes, exactly 4 lines before
  • Nir
    Nir over 8 years
    It can overlap as you can see in my edited question
  • Nir
    Nir over 8 years
    I'm not sure I can use your example. Have a look in my edit
  • terdon
    terdon over 8 years
    @nir and what output would you like to see from that input? You still haven't explained what exactly you are trying to do. See my original comment on your answer. And did you see the answers on the duplicate? Do they help?
  • Nir
    Nir over 8 years
    The dup will make it hard to code. The only thing I think can help is your answer but I need to run some tests for that
  • terdon
    terdon over 8 years
    @nir you still haven't explained what you are actually looking for, or answered the comment I left yesterday under your answer. You need to tell us—in words—what you need. Will Database name always be exactly 4 lines before Directory entry type.*Indirect or can it be anywhere in the preceding 4 lines? What is your final objective? The whole thing can be done in awk but only if you explain clearly what you actually need.
  • Nir
    Nir over 8 years
    I hope now I answered everything.
  • terdon
    terdon over 8 years
    @nir yes, thank you. Have a look at the updated answer.