1

I want to get the end date for an installed subscription, and currently using

subscription-manager list --installed | grep Ends | awk '{print $2 }')

The complexity comes when there are multiple subscriptions. How can I get just the end date and name that matches a subscription where the name has "Server" in it?

+-------------------------------------------+
    Installed Product Status
+-------------------------------------------+
Product Name:   Red Hat Enterprise Linux Server
Product ID:     69
Version:        7.7
Arch:           x86_64
Status:         Subscribed
Status Details:
Starts:         27/11/19
Ends:           27/11/20

Product Name:   Red Hat Enterprise Linux High Availability for x86_64
Product ID:     83
Version:        7.7
Arch:           x86_64
Status:         Subscribed
Status Details:
Starts:         27/11/19
Ends:           27/11/20
2
  • Not to second-guess you, but do you maybe want the "Ends" date for "stanzas" or "paragraphs" for every "Product Name"? Or do you only want the 'end' date for the "RHEL Server" Product? – Jeff Schaller May 4 '20 at 15:53
  • @JeffSchaller This is ideally what I'll want; the end date and name – Booboo May 4 '20 at 16:32
1

This is basically a shorter version of AdminBee's approach:

$ subscription-manager list --installed | 
    awk '{
            if(sub(/^Product Name: */,"")){
                a=0; 
                n=$0;
                if(/<Server>/){ a++ }
            } 
          }/Ends/ && a{print n,$2}'  
Red Hat Enterprise Linux Server 27/11/20

The script will set a to 0 if the current line begins with Product Name:, since we want to reset it every time and then, if the line also has the string Server, it will set it to 1. Then, if the current line starts with Ends:, and a is not 0, it will print the second field.

Note that this will also match for a Product Name: that contains notAServer or anything else that contains Server. To limit to word matches only, you can use this instead (assuming you have gawk, GNU awk):

subscription-manager list --installed | 
    gawk '{if(sub(/^Product Name: */,"")){a=0; n=$0;if(/\<Server\>/){a++}} }/Ends/ && a{print n,$2}'
2
  • OP requested $2 and name: subscription-manager list --installed | awk '{if(/^Product Name:/){a=0; if(/Server/){a=1;$1=$2="";name=$0}} }/^Ends:/ && a{print $2 name}' – Cbhihe May 5 '20 at 7:44
  • @Cbhihe thanks. I read "I want to get the end date" and the code the OP was showing, and missed the request for the name as well in the second paragraph. – terdon May 5 '20 at 9:22
2

Please note that it is rarely necessary to combine awk, sed and grep for a single task. In your case, the following should work:

subscription-manager list --installed | awk '$2=="Name:" && $0~/Server/ {relevant_section=1;print;} \
$1=="Ends:" && (relevant_section==1) {relevant_section=0;print;}'

This will set a flag relevant_section to 1 if a line that starts with "Product Name:" (or rather, where the second space-separated token is Name:) contains the string Server. For convenience, this line is also printed.

When a line starting with Ends: is encountered while the flag is 1, it will print that line and reset the flag to 0.

If you really only want the end date printed, you can shorten it as:

subscription-manager list --installed | awk '$2=="Name:" && $0~/Server/ {relevant_section=1;} \
$1=="Ends:" && (relevant_section==1) {relevant_section=0;print $2;}'
0

Using Miller

$ tail -n +4 subscriptions | mlr --xtab --ips : --ops ': ' \
    filter '${Product Name} =~ "Server"' then cut -f 'Product Name,Ends'
Product Name:    Red Hat Enterprise Linux Server
Ends:            27/11/20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.