Get a string if two words not from the string match - linux

On a Linux system I have some output like this:
Subject = CN=User_A,OU=users
Status = Valid Kind = IKE Serial = 98505 DP = 9
Not_Before: Wed Jun 15 13:53:55 2022 Not_After: Sun Jun 25 08:25:20 2023
Subject = CN=User_B,OU=users
Status = Valid Kind = IKE Serial = 98934 DP = 8
Not_Before: Sun Apr 18 18:24:16 2021 Not_After: Fri Apr 21 18:24:16 2023
I can use | grep 2022 | grep Jun to find certain data, but how can get Subject line in the output? I need to get the username whose certificate is about to expire ) Something like "Show me the Subject if "grep 2022 | grep Jun"".
Thank you in advance!

What about this:
grep -B 2 "2022" test.txt | grep -o "CN=[A-Za-z0-1_]*" | cut -c 4-
grep -B 2 // show the matching line and two lines before too.
[A-Za-z0-1_]* // any character, being letters, digits and an underscore
grep -o "CN=[...]"
// show only the part, containing "CN=", followed by ...
cut -c 4- // instead of "CN=...", only show "..." (starting at 4th character)

Using grep
$ grep -m2 -e '^Subject' -e 'Jun' -e '2022' input_file
Subject = CN=User_A,OU=users
Not_Before: Wed Jun 15 13:53:55 2022 Not_After: Sun Jun 25 08:25:20 2023
Using sed
$ sed -n '/^Subject/{p;:a;n;/Jun\|2022/p;ba}' input_file
Subject = CN=User_A,OU=users
Not_Before: Wed Jun 15 13:53:55 2022 Not_After: Sun Jun 25 08:25:20 2023

Related

How to sort data based on date field by excluding header

I have a scenario where I have below data in file
which need to be sorted based on date column , first line is the headers it should not be sorted
NAME|AGE|COURSE|DATES
v1|31|MC|12 JUL 2019
v2|33|MB|4 JUL 2019
v3|12|GG|13 JUL 2019
v4|21|JJ|7 JUL 2019
My code :
sort -n -k k4 /d/file.txt
This above code does not sort my data
Expected Output :
NAME|AGE|COURSE|DATES
v4|21|JJ|7 JUL 2019
v2|33|MB|4 JUL 2019
v1|31|MC|12 JUL 2019
v3|12|GG|13 JUL 2019
The way do to this is with Command Grouping where you can extract the header from an input stream, print it, and consume the remaining data:
{
IFS= read -r header
echo "$header"
sort ...
} < file.txt
However, sorting dates with that format is tricky. Here's how you have to do it so the output is sorted chronologically. This assumes GNU sort:
$ cat file.txt # I added a couple of extra records
NAME|AGE|COURSE|DATES
v1|31|MC|12 JUL 2019
v2|33|MB|4 JUL 2019
v3|12|GG|13 JUL 2019
v4|21|JJ|7 JUL 2019
11|22|33|1 JUL 2020
aa|bb|cc|10 AUG 2019
$ {
IFS= read -r header
echo "$header"
sort -t'|' -n -s -k4 | sort -M -s -k 2,2 | sort -n -s -k 3,3
} < file.txt
NAME|AGE|COURSE|DATES
v2|33|MB|4 JUL 2019
v4|21|JJ|7 JUL 2019
v1|31|MC|12 JUL 2019
v3|12|GG|13 JUL 2019
aa|bb|cc|10 AUG 2019
11|22|33|1 JUL 2020
That uses the GNU sort "stable" option so you sort first by day, then by month, then by year.
Borrowing #glennjackman's sample input, this will work using any versions of the mandatory Unix tools awk, sort, and cut:
$ awk '
BEGIN { FS="|"; OFS="\t" }
{
split($NF,d," ")
mthNr = (index("JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC",d[2])+2)/3
print (NR>1), d[3], mthNr, d[1], NR, $0
}
' file.txt |
sort -k1,1n -k2,2n -k3,3n -k4,4n -k5,5n |
cut -f6-
NAME|AGE|COURSE|DATES
v2|33|MB|4 JUL 2019
v4|21|JJ|7 JUL 2019
v1|31|MC|12 JUL 2019
v3|12|GG|13 JUL 2019
aa|bb|cc|10 AUG 2019
11|22|33|1 JUL 2020

how can i cut off the strings from an output in Bash shell?

The command i run is as follows:
rpm -qi setup | grep Install
The output of the command:
Install Date: Do 30 Jul 2020 15:55:28 CEST
I would like to edit this output further more in order to remain with just:
30 Jul 2020
And the rest of the output not to be displayed.
What best editing way in bash can i possibly simply get this end result?
Use grep -Po like so (-P = use Perl regex engine, and -o = print just the match, not the entire line):
echo '**Install Date: Do 30 Jul 2020 15:55:28 CEST**' | grep -Po '\d{1,2}\s+\w{3}\s+\d{4}'
You can also use cut like so (-d' ' = split on blanks, -f4-6 =
print fields 4 through 6):
echo '**Install Date: Do 30 Jul 2020 15:55:28 CEST**' | cut -d' ' -f4-6
Output:
30 Jul 2020
You can do it using just rpmqueryformat and bashprintf:
$ printf '%(%d %b %Y)T\n' $(rpm -q --queryformat '%{INSTALLTIME}\n' setup)
29 Apr 2020

Filter between version names and version numbers

when I run the script kit_version.sh I get the following output
# ./kit_version.bash
--- USAW Kits ---
RPM Kits Installed Time
------------------------------------ ---------------------------------
APP-IR-LRPS-1.1.0.0-01 Thu 15 Nov 2012 11:10:20 AM IST
APP-V-LRPS-4.3.7.0-01 Mon 15 Oct 2012 04:27:54 PM IST
batter-ic-4.3.0.0-04 Mon 24 Feb 2014 02:10:21 PM IST
CSHRS-Monitoring-5.0.0.0-03 Mon 24 Feb 2014 03:32:43 PM IST
CS-RH-watchdog-conf-5.0.0.0-03 Mon 24 Feb 2014 03:32:42 PM IST
CSe-OSP-Bin-5.0.0.0-01 Mon 24 Feb 2014 03:28:00 PM IST
sca_core_2.5.7.0-7 Sun 29 Mar 2015 02:36:46 PM IDT
sca_data:80.7.0-7 Sun 29 Mar 2015 02:37:04 PM IDT
.
.
.
How to filter the output so I get in the first field only the package name and the second field
only the version number as the following:
./kit_version.bash | ......
APP-IR-LRPS 1.1.0.0-01
APP-V-LRPS 4.3.7.0-01
batter-ic 4.3.0.0-04
CSHRS-Monitoring 5.0.0.0-03
CS-RH-watchdog-conf 5.0.0.0-03
CSe-OSP-Bin 5.0.0.0-01
sca_core 2.5.7.0-7
sca_data 80.7.0-7
Remark – the separator between the version name to version number could be different char
With GNU awk, I can imagine
./kit_version.bash | gawk '{ print gensub(/.([0-9.]+-[0-9.]+)$/, "\t\\1", 1, $1) }'
This will replace the character before a string matching a version number at the end of the first field with a tab and print the result of that substitution. To cut off the first three lines, use
awk 'NR > 3 { print gensub(/.([0-9.]+-[0-9.]+)$/, "\t\\1", 1, $1) }'
that is, add the NR > 3 condition.
Alternatively with sed:
./kit_version.bash | sed '1d;2d;3d;s/[[:space:]].*//;s/.\([0-9.]\+-[0-9.]\+\)$/\t\1/'
That is:
1d # first three lines: delete
2d
3d
s/[[:space:]].*// # remove everything after the first space,
# i.e., everything except the first field
s/.\([0-9.]\+-[0-9.]\+\)$/\t\1/ # then substitute as before.
This depends on no packages ending with a number while also being delimited from the version number by a period. That is to say,
# vvvvvvvv-- if this is supposed to be the version
somepackage2.3.4.5-10
will not work properly (it will give somepackag 2.3.4.5-10). It seems unlikely that this format is allowed, though.
./kit_version.bash \
| sed 's/^[[:space:]]*\([^[:space:]]*\).*/\1/;T clean;s/[-._]\([0-9][0-9._-]*\)$/\t\1/;t;:clean;s/.*//'
reformat the line (remove heading space and trialing info)
if no modif, go to cleaning the line
reformat to separate version from name
Only with GNU sed due to T option (or need a t jump;b clean^J:jump^J on posix version where ^J is a real new line)

how can I add number lines to a file with in this script

So I have this script file that automatically saves the date and time to a file when the terminal is open. But i'm having a hard time putting number lines in it. I tried cat -n, grep -n, ls -l, but I either get errors or doesn't increment. As you can see:
My Script
echo $(date) >> .test
I would like to see something like this:
0 : Tue Feb 15 13:10 EST 2014
1 : Tue Feb 18 12:10 EST 2014
2 : Tue Feb 18 10:10 EST 2014
3 : Tue Feb 19 13:22 EST 2014
If you pipe the result into cat, you can use the -n option to number each line like so:
ls | grep "whatever" | cat -n
Here's a solution:
echo $(wc -l < filename) : $(date) >> filename
Try saving the last number in a file. Then, in your script, read in the number, increment it, and write it back to the file. If you are using bash, something like this should work.
num=$(cat number.txt)
num=$(($num+1))
echo $num > number.txt

Using variables with sed

I'm trying to delete a part of a file using sed in Linux (Ubuntu). Specifically, I want to delete the first lines of a log file until the first occurrence of the current system date (using the pattern '10 Jan 13').
So, I store the date in a variable
root#server:/# VAR_DATE=`date -R | cut -c6-11`
And after that, I use sed
root#server:/# cat log_file.txt | sed -n -e '/$VAR_DATE/,$p'
But it doesn't work. I've tried a lot of combinations with the same result:
root#server:/# cat log_file.txt | sed -n -e '/"$VAR_DATE"/,$p'
root#server:/# cat log_file.txt | sed -n -e '/"${VAR_DATE}"/,$p'
root#server:/# cat log_file.txt | sed -n -e "/$VAR_DATE/,$p"
What I'm doing wrong?
Use double quotes so the variable $vardate gets expanded by the shell and escape the last $ so it's not expanded by the shell sed -n "/$vardate/,\$p" file:
$ cat file
6 Jan 13
7 Jan 13
8 Jan 13
9 Jan 13
10 Jan 13
11 Jan 13
12 Jan 13
13 Jan 13
$ vardate="10 Jan 13"
$ sed -n "/$vardate/,\$p" file
10 Jan 13
11 Jan 13
12 Jan 13
13 Jan 13

Resources