Reputation: 51
I need some solution to replace some string. I Have a "file" with this on the content:
23674, ICMP ping, OK, 1, 2016-08-25 17:11:02
23686, Ping, OK, 1, 2016-08-25 16:05:04
23689, SSH Service, OK, 1, 2016-08-25 16:05:49
23693, System Free Space, OK, 97.9560, 2016-08-25 16:06:49
23713, System Free Space, OK, 88.0078, 2016-09-20 18:02:22
23745, C:\ Free, OK, 63.2227, 2016-09-21 10:57:03
I used this code to take "Free" value on it like this:
grep Free file.txt |grep OK | cut -d K -f 2 |cut -d , -f 2 |cut -d . -f 1
Then i got this result:
97
88
63
I need to insert "%" into the result using this code:
grep Free rs.txt |grep OK | cut -d K -f 2 |cut -d , -f 2 |cut -d . -f 1 |sed 's/$/%/g'
The result like this:
97%
88%
63%
My question is, how to replace the value on the file for example "97.9560" with new result "97%" etc.
Kindly give me an advice.
Thanks
Upvotes: 2
Views: 79
Reputation: 23697
Couple of perl
solution
$ perl -pe 's/OK,\s*\d+\K\.\d+/%/ if /Free/' ip.txt
23674, ICMP ping, OK, 1, 2016-08-25 17:11:02
23686, Ping, OK, 1, 2016-08-25 16:05:04
23689, SSH Service, OK, 1, 2016-08-25 16:05:49
23693, System Free Space, OK, 97%, 2016-08-25 16:06:49
23713, System Free Space, OK, 88%, 2016-09-20 18:02:22
23745, C:\ Free, OK, 63%, 2016-09-21 10:57:03
OK,\s*\d+\K
positive lookbehind, OK,
followed by zero or more spaces and one or more digits\.\d+
dot followed by one or more digits%
, applied only when input line contains Free
Another way is to split input line on ,
and change 4th field
perl -F, -le '$F[3] =~ s/\.\d+/%/ if /Free/; print join",", @F' ip.txt
If result is as expected, changes can be done inplace with
perl -i
no backup
or
perl -i.bkp
with backup
Upvotes: 0
Reputation: 18411
Here is awk
version solution:
awk -v OFS=, -F, '/Free.*OK/ {split($4,a,"."); $4=a[1]"%"}1' infile
23674, ICMP ping, OK, 1, 2016-08-25 17:11:02
23686, Ping, OK, 1, 2016-08-25 16:05:04
23689, SSH Service, OK, 1, 2016-08-25 16:05:49
23693, System Free Space, OK, 97%, 2016-08-25 16:06:49
23713, System Free Space, OK, 88%, 2016-09-20 18:02:22
23745, C:\ Free, OK, 63%, 2016-09-21 10:57:03
Explanation :
this awk
command will take actions on only those lines which contains Free
followed by OK
. As this file is a csv
file, get the 4th field and split into two parts separated by .
. print the part which is of interest after appending %
sign to it.
sed
is best suited for find and replace tasks as it support in-place replacement. However it can be achieved through awk
using following way :
awk -v OFS=, -F, '/Free.*OK/ {split($4,a,"."); $4=a[1]"%"}1' infile > infile.tmp && mv infile.tmp infile
Upvotes: 1
Reputation: 113984
To replace the value in the file:
sed -E -i.bak 's/(Free.*OK,[^.]*)[.][^,]*/\1%/' file.txt
Example:
$ sed -E -i.bak 's/(Free.*OK,[^.]*)[.][^,]*/\1%/' file.txt
$ cat file.txt
23674, ICMP ping, OK, 1, 2016-08-25 17:11:02
23686, Ping, OK, 1, 2016-08-25 16:05:04
23689, SSH Service, OK, 1, 2016-08-25 16:05:49
23693, System Free Space, OK, 97%, 2016-08-25 16:06:49
23713, System Free Space, OK, 88%, 2016-09-20 18:02:22
23745, C:\ Free, OK, 63%, 2016-09-21 10:57:03
-E
This tells sed to use extended regular expressions. This reduces the number of backslashes that we need.
-i.bak
This tells to change the file in-place, leaving a back-up file.
s/(Free.*OK,[^.]*)[.][^,]*/\1%/
This tells sed to make the substitution that you need. In this case, sed looks for text matching the regex (Free.*OK,[^.]*)[.][^,]*
. This matches Free
followed by OK,
followed by anything except a period, followed by a period, followed by anything except a comma. The parentheses cause everything from Free
to the last character before the period to be saved in group 1.
The text that was matched is replace by \1%
which means the text belonging to group 1, \1
, followed by a percent sign, %
.
Upvotes: 2