Reputation: 158
I have a text file (mcafee agent install script named install.sh) that contains many lines, including the following lines that I am interested in:
THIS_MAJOR=5
THIS_MINOR=0
THIS_PATCH=6
THIS_BUILD=491
I want to use awk to print the numbers from column 2 on each line as a dot separated version string on one line so that the output looks like this:
5.0.6.491
I am using the following awk command to match on the lines containing the version numbers in column 2, and to print the value and append the dot character with printf:
awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {printf("%s.", $2)}' /tmp/install.sh
Which prints out:
5.0.6.491.
I'm trying to avoid printing the last '.' character
Here's what I've tried so far
Using gsub to replace the '.' character.
Not ideal, because I should be able to tell awk to just not print the '.' if it's operating on the last line.
awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {printf("%s.", $2)} END{gsub(".","",$2)}' /tmp/install.sh
Attempt to use END and not print the last "." :
awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {printf("%s.", $2)} END{printf("$s", $2)}' /tmp/install.sh
Which no longer matches correctly on the lines that contain the version numbers.
Attempt to determine number of lines, and while not processing the last line, print the dot character, and on the last line, print without the dot character.
awk -v nlines=$(wc -l < $a) -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {printf("%s.", $2)} NR != nlines { printf("%s", $2)}' $a >> /tmp/install.sh
Which returns:
-bash: $a: ambiguous redirect
How can I get awk to not print the '.' character for the number from the last line?
Thanks
Upvotes: 4
Views: 633
Reputation: 203324
Personally I'd do it like this so the version number that's output is independent of the order the lines that make up the parts of the version number appear in the input and you can trivially modify it to print whatever else is added to the input in any order:
$ awk -F'=' -v OFS='.' 'sub(/^THIS_/,""){v[$1]=$2} END{print v["MAJOR"], v["MINOR"], v["PATCH"], v["BUILD"]}' file
5.0.6.491
Upvotes: 1
Reputation: 67467
paste
is for this
$ awk -F= '/THIS_(MAJOR|MINOR|PATCH|BUILD)/{print $2}' file | paste -sd.
5.0.6.491
Upvotes: 1
Reputation: 3714
Not sure I understand the requirements in the comments, but something like this would work and isn't too far off from what you've tried. You just need to swap to prepending a dot to a match instead of appending it, and skip the first one.
awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {(output=="")? output=$2 : output=output"."$2} END {print output}'
Matching is the same, the logic was changed to:
{(output=="")? output=$2 : output=output"."$2} END {print output}
Which checks if a variable named output
is empty (which it will be on the first match) and then set it to $2
if so, and if not, it appends a .
following by the value of $2
.
e.g.
$ cat so.txt
sagfdsga
asgasd
asdg
sdag
asg
:wq
234
534215.4361436
i
favorite
I have a text file (mcafee agent install script named install.sh) that contains many lines, including the following lines that I am interested in:
THIS_MAJOR=5
THIS_MINOR=0
THIS_PATCH=6
THIS_BUILD=491
sagfdsga
asgasd
asdg
sdag
$ awk -F "=" '/^THIS_/ && /MAJOR|MINOR|PATCH|BUILD/ && !/AGENT/ {(output=="")? output=$2 : output=output"."$2} END {print output}' so.txt
5.0.6.491
Upvotes: 3