如何在 Awk 或 Sed 中将数学与正则表达式混合?

发布于 2024-09-18 10:17:47 字数 702 浏览 3 评论 0原文

我之前在 sed 中使用过正则表达式,并使用过一些 awk,但不确定我在这里需要的确切语法...

我想做类似的事情:

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

第二个匹配项除以 2,然后放回到内联中编辑。

我读过 sed 不能做数学。

我可以单独使用 sed 或 awk 干净地完成此操作吗?请提出建议。

编辑 1
我认为我的询问的含义足够简单,但我想我可能没有给出足够好的我想要修改的数据样本。这是我要内联编辑的 *.conf 文件中的行的示例:

restartfreq        1250    ;# 2500steps = every 1.25 ps

我在下面发布了一个解决方案。我收到的两个答案都是关于将文本打印到终端,而不是内联编辑文件。我试图避免回答我自己的问题,但在这种情况下,我收到的答案都没有真正做到我所要求的(编辑文件,而不仅仅是打印编辑的行),并且它们比我的解决方案长得多和/或需要额外的linux除了 awk 或 sed 之外的程序。

不过,我非常感谢您的帮助和反馈! :)

注意:正如我通常的免责声明,这不是一个家庭作业问题,我是一名化学工程研究员。

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 a chemical engineering researcher.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

下壹個目標 2024-09-25 10:17:47
$ cat script.awk
/restartfreq *[0-9]+/{
    $2 = $2/2
}
{print}
$ awk -f script.awk my_file.conf

如果您始终希望数字为整数,请将 $2/2 更改为 int($2/2)


要覆盖该文件,您可以使用海绵(如果您有 moreutils 可用)或一个临时文件。

后者应该是不言自明的。
海绵可以让你做到:

$ awk -f script.awk my_file.conf | sponge my_file.conf
$ 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
若水微香 2024-09-25 10:17:47

这就是仅使用 awk 的方式

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

this is how you do it with awk only

 awk '$1=="restartfreq"{$2=$2/2;}1' file > t && mv t file
孤星 2024-09-25 10:17:47

这可能符合您正在寻找的内容:

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

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

$ echo 'restart 4' | awk '{$2=$2/2; print}'
restart 2
罪#恶を代价 2024-09-25 10:17:47

以下解决方案实际上编辑内联文件,仅使用一个命令,并且比其他建议的解决方案(恕我直言)更优雅一些。

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

向丹尼斯等人道歉。 al 回答我自己的问题,但我觉得这是最好的解决方案,希望它能让阅读此内容的其他人受益...

编辑 1

哎呀我撒谎了。这也只是打印到终端...

我花了很长时间才找到,但这有效,仅使用 sed 和 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

也许这可以简化,但至少它有效! :)

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! :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文