开发者

How Can I Mix Math with Regex's in Awk or Sed?

开发者 https://www.devze.com 2023-01-15 09:53 出处:网络
I\'ve used regex\'s in sed before and used a bit of awk, but am unsure of the exact syntax I need here...

I've used regex's in sed before and used a bit of awk, but am unsure of the exact syntax I need here...

I want to do something like:

sed -i 's/restartfreq\([\s]\)*\([0-9]\)*/restartfreq\1$((\2/2))/2/g' \
    my_file.conf

where the second match is divided by 2 and then put back in the inline edit.

I've read though that sed can't do math.

Can I do this cleanly with sed or awk alone? Suggestions please.

Edit 1

I thought the meaning of my inquiry was straightforward enough, but I guess I might not have given a good enough sample of the data I want to modify. Here's and example of the line in my *.conf file I want to edit inline:

restartfreq        1250    ;# 2500steps = every 1.25 ps

I've posted a solution below. Both of the answers I received were with regards to printing text to the terminal, not editing a file inline. I try to avoid answering my own question, but in this case neither of the answers I received really did what I requested (edit the file, not just print the edited line) and they were substantially longer than my solution and/or required additional linux programs besides just awk or sed.

I do appreciate the help and feedback, though! :)

NOTE: As my usual disclaimer, this is not a homework question, I am开发者_如何学JAVA a chemical engineering researcher.


$ cat script.awk
/restartfreq *[0-9]+/{
    $2 = $2/2
}
{print}
$ awk -f script.awk my_file.conf

If you always want the number to be an integer, change $2/2 to int($2/2).


To overwrite the file, you could either use sponge (if you have moreutils available) or a temporary file.

The latter should be self-explanatory.
Sponge lets you do:

$ awk -f script.awk my_file.conf | sponge my_file.conf


this is how you do it with awk only

 awk '$1=="restartfreq"{$2=$2/2;}1' file > t && mv t file


This may be along the lines of what you're looking for:

$ echo 'restart 4' | awk '{$2=$2/2; print}'
restart 2


The following solution actually edits the file inline, only uses one command, and is a bit more elegant than the other proposed solutions (IMHO).

awk '{gsub(/restartfreq\s*[0-9]+/,$2/2,$2)}' my_file.conf

Apologies to Dennis, et. al for answering my own question, but I feel this is the best solution and hopefully it will benefit others who read this...

Edit 1

Whoops I lied. That just prints to the terminal too...

It took me a long time to find, but this works, using only sed and awk:

sed -i '/restartfreq/s/'`sed -n 's/restartfreq*/&/p' my_file.conf | awk '{print $2}'`'/'`sed -n 's/restartfreq*/&/p' my_file.conf | awk '{print $2/2}'`'/g' my_file.conf

Perhaps this can be streamlined, but at least it works! :)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号