Following may help you in same, following code will check if field 1st is less than 300 then it will print 300 at first field else it will print actual 1st field's values.
awk '{$1=$1<300?300:$1} 1' Input_file
Output will be as follows.
300 32000 32 128
Also you can redirect this to a output file as per your requirement too.
If I understood you correctly you are trying to take OUTPUT or EDIT the same file which is being used for input as well, then I can say there no option present in awk to do so. You can create a script and execute like following.
Could you please try the same and let me know if this helps, kindly try the same first with same details a test file
and if All is Well then you can try with actual file too.
cat script.ksh
VALUE=`awk '/kernel\.sem/ {if($3 < 300){print 1}}' Input_file`
if [[ $VALUE -eq 1 ]]
then
sed -i '/kernel.sem/s/\(.*= \)\(...\)\(.*\)/\1 300 \3/g' Input_file
else
echo "Values are fine nothing to do."
fi
This is extremely dangerous code. Depending on the size of the input file and the location of the line being modified in the file, this may truncate your input file to size zero instead of updating a field in one or more lines in the file.
NEVER, try to read and write a file that might be larger than the size of the 1st read performed by awk or you will destroy your input file. (And, since there is no requirement placed on awk for the sizes of the reads it performs, NEVER, NEVER, NEVER do this.)
Using sed -i to update a system configuration file could also leave you with an unbootable system if your system loses power in the middle of an update. Ranvinder's suggestion in post #9 is much safer (using a temp file and moving or copying the updated file after it has been fixed), but it should verify that the awk command returned a zero exit status before attempting the mv on the next line.
However, it would be much better to create the temp file in the same directory as the file being updated (same filesystem is sufficient, but in case more file systems are created in the future, same directory is safer), so the mv is just a rename() which will always leave you with either the original configuration file or the updated configuartion file in place. (Of course, any change to a file could be corrupted by a disk block or controller going bad while you're making the update; but this method eliminates several other error cases that could destroy your data.)
[quote="stew,post:17,topic:350679"]
Thanks Don. I have two doubts in your code
($3 + 0) - why you use
d + 0 in here
Because ($3 < "300")
performs a string comparison and would give you the wrong result if in some cases. For example, if the current contents of field 3 was 1000, it would reduce it to 300; and if the current contents of field 3 was 40, it wouldn't increase it to 300.
Yes, the default action in awk when a condition evaluates to true (non-zero) is to print the current line.
Did you try what I suggested? Did it give you the wrong results for any value on the kernel.sem line in your sysctl.conf file(s)?
yes. your code is working perfectly. I am using this sample peice for puppet automation. so for awk part I don't hard code anything. I will write all vlaues to some other yaml file and will ivoke that value variable into puppet awk function.
I have no idea what peice, puppet automation, vlaues, nor yaml mean, and there is no puppet() function in this awk script??? The awk variable value is not defined in this script and comparing the number in field 3 of a line to the entire line as a string (containing something like:
kernel.sem = 250 32000 32 128250
which is what $undefined_variable will expand to in your awk script with your sample input file) is not what you want. If you want to parameterize the threshold value for changes instead of hard coding it to 300, you need something like:
Please DO NOT use the name sysctl.conf.bkp in this script. It is not a backup file; it is a temp file used as a work area for this script. And, if the number found in the 3rd field on the "kernel.sem" line is greater than or equal to your value variable, it will only contain a subset of your file (since this awk script returns an error status and stops processing input if it is not going to change that line. This file will NEVER contain the original contents of your input file unless your input file does not contain a line that contains the string "kernel.sem"! This leaves the current sysctl.conf in place (instead of replacing it with a copy of itself) if no changes are being made, and runs faster than processing the rest of the file and replacing an unmodified file.
Note that I added an anchor to the ERE selecting the line to be changed in case your configuration file might contain a comment that explains why kernel.conf is being set.