如何找到/使用sed / awk的更换和增加匹配的号码? [英] How to find/replace and increment a matched number with sed/awk?

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

问题描述

开门见山,我想知道如何使用grep /查找/ SED / AWK匹配某个字符串(以数字结尾)和1递增这个数字我来最接近的是连接1到年底(该作品不够好),因为主要的一点是简单地更改值。下面是目前我在做什么:

 找到。型F | xargs的SED -i的/ \\(\\?cache_version \\ = [0-9] \\ + \\)/ \\ 11 / G'

因为我无法弄清楚如何递增的数字,我抓住了整个事情,只是附加了1。之前,我有这样的事情:

 找到。型F | xargs的SED -i的/ \\?cache_version \\ = \\([0-9] \\ + \\)/?cache_version = \\ 11 / G'

所以,至少我知道如何捕捉到我所需要的。

而不是解释什么,这是对的,我就解释一下我想要它做的。它应该找到任何文件中的文本,递归,基于当前目录(并不重要,它可以是任何目录,所以我以后配置),符合?cache_version =用一个数字。然后,它会增加这个数字和文件中替换它。

目前的东西,我有以上的作品,它只是我不能增加该发现号在最后。这将是更好的,以便能够增加,而不是追加一个1,以使将来的值不会是11,111,1111,11111,等等。

我已经通过几十条/解释了,常常不够,建议是使用 AWK ,但我不能为我的生活混合。最接近我来使用 AWK ,它实际上并没有取代任何东西,就是:

 的grep -Pro(小于??= \\ cache_version =)[0-9] +。 | awk的-F:'{打印匹配,$ 2 + 1}

我不知道是否有一些方法来管一 SED 结尾,并通过原文件名,这样 SED 可以有文件名和递增的数字(从 AWK ),或任何需要的的xargs

从技术上讲,这个数字已经没有意义;这种替换主要是为了确保有一个新的数字出现,肯定比上届不同的100%。所以当我在写这个问题,我意识到,我还不如用系统时间 - 纪元以来的秒数(通常使用AJAX来消除对随后的雷同的请求缓存技术)。我结束了这一点,而且似乎完美的:

  CXREPLACETIME =`日期+%s`;找 。型F | xargs的sed的-iS / \\(\\?cache_version \\ = \\)[0-9] \\ + / \\ $ 1 CXREPLACETIME / G

(我保存的价值首先让所有的文件得到相同的值,如果它跨越多个秒无论何种原因)

但我还是很想知道原来的问题,在递增匹配的数字。我猜一个简单的解决办法是让一个bash脚本,不过,我以为会有不是通过每一个文件递归循环并检查其内容,然后匹配更换更简单的方法,因为它只是递增匹配的数字...别的不多逻辑。我只是不希望写入任何其他文件或类似的东西 - 它应该做的很到位,像 SED 与我选项执行

解决方案

我想找到的文件是不是你困难的部分。因此,我刚去的地步,做+1计算。如果你有 GNU SED ,它可以这样做:

 的sed -r的/(。*)(\\?cache_version =)([0-9] +)(。*)/回声\\ 1 \\ 2 $(( \\ 3 + 1))\\ 4/ GE'文件

让我们来举个例子:

 肯特$猫测试
ELLO
barbaz?cache_version = 3fooooo
再见肯特$ SED -r的/(。*)(\\?cache_version =)([0-9] +)(。*)/回声\\ 1 \\ 2 $((\\ 3 + 1))\\ 4/ GE的测试
ELLO
barbaz?cache_version = 4fooooo
再见

如果你愿意,你可以添加-i选项。

修改

/ E 允许你匹配的部分传递到外部命令,并做替代与执行结果。 GNU sed的只有

看到这样的例子:外部命令/工具回声 BC 用于

 肯特$回声结果是:3 * 3| sed的-r的/(结果:)/回声\\ $ 1(回声\\ 2\\ |(。*) BC)/ GE

给出输出:

 结果:9

您可以使用其他功能强大的外部命令,如剪切,sed的(再次),AWK ...

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'

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.

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.

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.

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 }'

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.

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)

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.

解决方案

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 "\1\2$((\3+1))\4"/ge' file

let's take an example:

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

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

you could add -i option if you like.

edit

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

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'       

gives output:

result:9

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

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

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