如何使用 sed/awk 查找/替换和递增匹配的数字? [英] How to find/replace and increment a matched number with sed/awk?

查看:27
本文介绍了如何使用 sed/awk 查找/替换和递增匹配的数字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直截了当,我想知道如何使用 grep/find/sed/awk 来匹配某个字符串(以数字结尾)并将该数字增加 1.我最接近的是连接1 到最后(效果很好),因为重点是简单地更改值.这是我目前正在做的事情:

Straight to the point, I'm wondering how to use grep/find/sed/awk to match a certain string (that ends with a number) and increment that number by 1. The closest I've come is to concatenate a 1 to the end (which works well enough) because the main point is to simply change the value. Here's what I'm currently doing:

find . -type f | xargs sed -i 's/(?cache_version=[0-9]+)/11/g'

由于我不知道如何增加数字,所以我捕获了整个内容并附加了一个1".以前,我有这样的事情:

Since I couldn't figure out how to increment the number, I captured the whole thing and just appended a "1". Before, I had something like this:

find . -type f | xargs sed -i 's/?cache_version=([0-9]+)/?cache_version=11/g'

所以至少我知道如何捕捉我需要的东西.

So at least I understand how to capture what I need.

我不会解释这是做什么的,而是解释我想要它做什么.它应该根据当前目录递归地查找任何文件中的文本(不重要,它可以是任何目录,所以我稍后会配置它),匹配?cache_version="和一个数字.然后它会增加这个数字并在文件中替换它.

Instead of explaining what this is for, I'll just explain what I want it to do. It should find text in any file, recursively, based on the current directory (isn't important, it could be any directory, so I'd configure that later), that matches "?cache_version=" with a number. It will then increment that number and replace it in the file.

目前我上面的东西有效,只是我不能在最后增加找到的数字.能够递增而不是附加1"会更好,这样未来的值就不会是11"、111"、1111"、11111"等.

Currently the stuff I have above works, it's just that I can't increment that found number at the end. It would be nicer to be able to increment instead of appending a "1" so that the future values wouldn't be "11", "111", "1111", "11111", and so on.

我已经阅读了数十篇文章/解释,而且通常情况下,建议使用 awk,但我终生无法混合使用它们.我最接近使用 awk 的方法是:

I've gone through dozens of articles/explanations, and often enough, the suggestion is to use awk, but I cannot for the life of me mix them. The closest I came to using awk, which doesn't actually replace anything, is:

grep -Pro '(?<=?cache_version=)[0-9]+' . | awk -F: '{ print "match is", $2+1 }'

我想知道是否有某种方法可以在末尾通过管道传递 sed 并传递原始文件名,以便 sed 可以具有文件名和递增编号(来自 awk),或者 xargs 所需要的任何东西.

I'm wondering if there's some way to pipe a sed at the end and pass the original file name so that sed can have the file name and incremented number (from the awk), or whatever it needs that xargs has.

从技术上讲,这个数字并不重要;这种替换主要是为了确保那里有一个新号码,100% 肯定与上一个不同.因此,当我在写这个问题时,我意识到我最好使用系统时间 - 自纪元以来的秒数(AJAX 经常使用的技术来消除后续相同"请求的缓存).我最终得到了这个,它看起来很完美:

Technically, this number has no importance; this replacement is mainly to make sure there is a new number there, 100% for sure different than the last. So as I was writing this question, I realized I might as well use the system time - seconds since epoch (the technique often used by AJAX to eliminate caching for subsequent "identical" requests). I ended up with this, and it seems perfect:

CXREPLACETIME=`date +%s`; find . -type f | xargs sed -i "s/(?cache_version=)[0-9]+/1$CXREPLACETIME/g"

(我首先存储该值,以便所有文件都获得相同的值,以防它因任何原因跨越多秒)

(I store the value first so all files get the same value, in case it spans multiple seconds for whatever reason)

但我仍然很想知道增加匹配数字的原始问题.我猜一个简单的解决方案是使它成为一个 bash 脚本,但是,我认为还有比递归遍历每个文件并检查其内容是否匹配然后替换更简单的方法,因为它只是增加匹配的数字...没有其他逻辑.我只是不想写入任何其他文件或类似的东西 - 它应该就地完成,就像 sed 对i"选项所做的那样.

But I would still love to know the original question, on incrementing a matched number. I'm guessing an easy solution would be to make it a bash script, but still, I thought there would be an easier way than looping through every file recursively and checking its contents for a match then replacing, since it's simply incrementing a matched number...not much else logic. I just don't want to write to any other files or something like that - it should do it in place, like sed does with the "i" option.

推荐答案

我认为查找文件对您来说并不困难.因此,我只是切入正题,进行+1 计算.如果您有 gnu sed,可以通过以下方式完成:

I think finding file isn't the difficult part for you. I therefore just go to the point, to do the +1 calculation. If you have gnu sed, it could be done in this way:

sed -r 's/(.*)(?cache_version=)([0-9]+)(.*)/echo "12$((3+1))4"/ge' file

举个例子:

kent$  cat test 
ello
barbaz?cache_version=3fooooo
bye

kent$  sed -r 's/(.*)(?cache_version=)([0-9]+)(.*)/echo "12$((3+1))4"/ge' test     
ello                                                                             
barbaz?cache_version=4fooooo
bye

如果您愿意,可以添加 -i 选项.

you could add -i option if you like.

编辑

/e 允许您将匹配的部分传递给外部命令,并用执行结果进行替换.仅限 Gnu sed.

/e allows you to pass matched part to external command, and do substitution with the execution result. Gnu sed only.

看这个例子:使用外部命令/工具echobc

see this example: external command/tool echo, bc are used

kent$  echo "result:3*3"|sed -r 's/(result:)(.*)/echo 1$(echo "2"|bc)/ge'       

给出输出:

result:9

您可以使用其他强大的外部命令,例如 cut、sed(再次)、awk...

you could use other powerful external command, like cut, sed (again), awk...

这篇关于如何使用 sed/awk 查找/替换和递增匹配的数字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆