grep -B does not work on AIX so I am looking for an alternative with awk
I have a file with the following content
05/25/2025 M 301510sa AIX is vulnerable to information disclosure (CVE-2024-13176) or arbitrary code execution or a denial of service (CVE-2024-9143) due to OpenSSL
openssl.base 3.0.15.1000 < 3.0.15.1001
06/15/2025 M 973013sab AIX is vulnerable to a denial of service (CVE-2025-26466) and a machine-in-the-middle attack (CVE-2025-26465) due to OpenSSH
openssh.base.server 9.7.3013.1000 < 9.7.3013.1001
06/15/2025 M 973013saa AIX is vulnerable to a denial of service (CVE-2025-26466) and a machine-in-the-middle attack (CVE-2025-26465) due to OpenSSH
openssh.base.client 9.7.3013.1000 < 9.7.3013.1001
and I want to get only the following
05/25/2025 M 301510sa AIX is vulnerable to information disclosure (CVE-2024-13176) or arbitrary code execution or a denial of service (CVE-2024-9143) due to OpenSSL
openssl.base 3.0.15.1000 < 3.0.15.1001
I want to pass as parameter the package which in this case is openssl.base
and I want to get the above result with the following command but it doesn't work
pkg=“openssl.base”; awk -v var1="$pkg" '/var1/{for(i=1;i<=x;)print a[i++];print}{for(i=1;i<x;i++)a[i]=a[i+1];a[x]=$0;}' x=1 file
I got the command from another site but I have not been able to make it work with what I want How can I find lines before my match if my grep doesn't support the -B option?
First issue to address is the assignment to pkg
.
You're wrapping openssl.base
in smart quotes instead of plain double quotes; those double quotes become part of the data and will never match (because the file does not contain smart quotes) so:
###### replace this:
pkg=“openssl.base” # smart quotes
###### with this:
pkg="openssl.base" # plain double quotes
Second issue is that /var1/
is looking for the literal string var1
. In this case you want to test for the 1st field matching the contents of variable var1
so:
###### replace this:
/var1/
###### with this:
$1 == var1
Updating OP's current awk
script with these 2 changes:
pkg="openssl.base"; awk -v var1="$pkg" '$1==var1{for(i=1;i<=x;)print a[i++];print}{for(i=1;i<x;i++)a[i]=a[i+1];a[x]=$0;}' x=1 file
This generates:
05/25/2025 M 301510sa AIX is vulnerable to information disclosure (CVE-2024-13176) or arbitrary code execution or a denial of service (CVE-2024-9143) due to OpenSSL
openssl.base 3.0.15.1000 < 3.0.15.1001
OP's awk
script is a modified version of this answer and has the downside of some excessive copying of array values.
This other answer to the same question should be a bit more efficient in that it overwrites array entries in the process of maintaining a rolling list of last N
lines. Modifying that answer to work with OP's data and requirement:
awk -v var1="$pkg" -v N=1 '
BEGIN { cl=1 }
$1 == var1 { for (i=cl; i<cl+N; i++)
print pLines[i % N]
print $0
cl=1
}
{ pLines[cl % N] = $0
cl++
}
' file
This also generates:
05/25/2025 M 301510sa AIX is vulnerable to information disclosure (CVE-2024-13176) or arbitrary code execution or a denial of service (CVE-2024-9143) due to OpenSSL
openssl.base 3.0.15.1000 < 3.0.15.1001