算术涉及的Sed替换可能吗?

Ter*_* Li 8 regex sed

我需要修改的文件包含以下内容:

block: 16, size: 16, start: 8, length: 4
Run Code Online (Sandbox Code Playgroud)

我想要这个文件,以便block,size的值除以2,而start,length的值将乘以2.

由于我必须对一大堆文件进行这样的修改,我正在考虑使用Sed为我做替换工作.但我不确定在匹配和替换过程中是否允许进行计算.

bra*_*zzi 9

我总是试图解决标有每一个问题使用sed.但是在这里完成你想要做的事情会很容易awk.(sed在这种情况下使用太难了.)所以,这是我的解决方案awk:

$ echo "block: 16, size: 16, start: 8, length: 4" | awk '{
    printf "%s %d, %s %d, %s %d, %s %d\n", $1, $2/2, $3, $4/2, $5, $6*2, $7, $8*2
}'
block: 8, size: 8, start: 16, length: 8
Run Code Online (Sandbox Code Playgroud)


jfg*_*956 6

(做这件事的合适工具是awk,但是为​​了获得sed练习的乐趣...)

它可能在sed.毕竟,乘以2是根据一些简单的规则替换最后一位数:

  • 0 - > 0
  • 1 - > 2
  • 2 - > 4
  • 3 - > 6
  • ...
  • 8 - > 16
  • 9 - > 18

为了处理进位数,每个规则应写两次.

这个可以运行的sed脚本与sed -f script输入行上的所有数字相乘2:

s/$/\n\n/
:loop
s/0\n1\n/\n\n1/;t loop
s/0\n\n/\n\n0/;t loop
s/1\n1\n/\n\n3/;t loop
s/1\n\n/\n\n2/;t loop
s/2\n1\n/\n\n5/;t loop
s/2\n\n/\n\n4/;t loop
s/3\n1\n/\n\n7/;t loop
s/3\n\n/\n\n6/;t loop
s/4\n1\n/\n\n9/;t loop
s/4\n\n/\n\n8/;t loop
s/5\n1\n/\n1\n1/;t loop
s/5\n\n/\n1\n0/;t loop
s/6\n1\n/\n1\n3/;t loop
s/6\n\n/\n1\n2/;t loop
s/7\n1\n/\n1\n5/;t loop
s/7\n\n/\n1\n4/;t loop
s/8\n1\n/\n1\n7/;t loop
s/8\n\n/\n1\n6/;t loop
s/9\n1\n/\n1\n9/;t loop
s/9\n\n/\n1\n8/;t loop
s/\n1\n/\n\n1/;t loop
s/\(.\)\n\n/\n\n\1/;t loop
s/^\n\n//
Run Code Online (Sandbox Code Playgroud)

将偶数除以2是相同的逻辑,但是从左到右而不是从右到左:

s/^/\n\n/
:loop
s/\n1\n0/5\n\n/;t loop
s/\n\n0/0\n\n/;t loop
s/\n1\n1/5\n1\n/;t loop
s/\n\n1/\n1\n/;t loop
s/\n1\n2/6\n\n/;t loop
s/\n\n2/1\n\n/;t loop
s/\n1\n3/6\n1\n/;t loop
s/\n\n3/2\n1\n/;t loop
s/\n1\n4/7\n\n/;t loop
s/\n\n4/2\n\n/;t loop
s/\n1\n5/7\n1\n/;t loop
s/\n\n5/2\n1\n/;t loop
s/\n1\n6/8\n\n/;t loop
s/\n\n6/3\n\n/;t loop
s/\n1\n7/8\n\n/;t loop
s/\n\n7/3\n1\n/;t loop
s/\n1\n8/9\n\n/;t loop
s/\n\n8/4\n\n/;t loop
s/\n1\n9/9\n1\n/;t loop
s/\n\n9/4\n1\n/;t loop
s/\n1\n/5\n\n/;t loop
s/\n\n\(.\)/\1\n\n/;t loop
s/\n\n$//
Run Code Online (Sandbox Code Playgroud)

结合这些,这个脚本完成工作:

h
s/, start.*//
s/^/\n\n/
t loopa
:loopa
s/\n1\n0/5\n\n/;t loopa
s/\n\n0/0\n\n/;t loopa
s/\n1\n1/5\n1\n/;t loopa
s/\n\n1/\n1\n/;t loopa
s/\n1\n2/6\n\n/;t loopa
s/\n\n2/1\n\n/;t loopa
s/\n1\n3/6\n1\n/;t loopa
s/\n\n3/2\n1\n/;t loopa
s/\n1\n4/7\n\n/;t loopa
s/\n\n4/2\n\n/;t loopa
s/\n1\n5/7\n1\n/;t loopa
s/\n\n5/2\n1\n/;t loopa
s/\n1\n6/8\n\n/;t loopa
s/\n\n6/3\n\n/;t loopa
s/\n1\n7/8\n\n/;t loopa
s/\n\n7/3\n1\n/;t loopa
s/\n1\n8/9\n\n/;t loopa
s/\n\n8/4\n\n/;t loopa
s/\n1\n9/9\n1\n/;t loopa
s/\n\n9/4\n1\n/;t loopa
s/\n1\n/5\n\n/;t loopa
s/\n\n\(.\)/\1\n\n/;t loopa
s/\n\n$//
H
g
s/.*, start/, start/
s/\n.*//
s/$/\n\n/
t loopb
:loopb
s/0\n1\n/\n\n1/;t loopb
s/0\n\n/\n\n0/;t loopb
s/1\n1\n/\n\n3/;t loopb
s/1\n\n/\n\n2/;t loopb
s/2\n1\n/\n\n5/;t loopb
s/2\n\n/\n\n4/;t loopb
s/3\n1\n/\n\n7/;t loopb
s/3\n\n/\n\n6/;t loopb
s/4\n1\n/\n\n9/;t loopb
s/4\n\n/\n\n8/;t loopb
s/5\n1\n/\n1\n1/;t loopb
s/5\n\n/\n1\n0/;t loopb
s/6\n1\n/\n1\n3/;t loopb
s/6\n\n/\n1\n2/;t loopb
s/7\n1\n/\n1\n5/;t loopb
s/7\n\n/\n1\n4/;t loopb
s/8\n1\n/\n1\n7/;t loopb
s/8\n\n/\n1\n6/;t loopb
s/9\n1\n/\n1\n9/;t loopb
s/9\n\n/\n1\n8/;t loopb
s/\n1\n/\n\n1/;t loopb
s/\(.\)\n\n/\n\n\1/;t loopb
s/^\n\n//
H
g
s/[^\n]*\n//
s/\n//
Run Code Online (Sandbox Code Playgroud)

(在awk思想中容易多了.)

注意:我曾经看过一个图灵机实现是sed,所以我试着记住任何可以用编程语言完成的事情都可以在sed中完成.那当然并不意味着sed是所有情况下的好工具.


gle*_*man 5

Perl在这里很有用:

perl -pe '
  s{(\D+)(\d+)(\D+)(\d+)(\D+)(\d+)(\D+)(\d+)}
   {$1 . $2/2 . $3 . $4/2 . $5 . $6*2 . $7 . $8*2}e
' file
Run Code Online (Sandbox Code Playgroud)

如果你想就地编辑你的文件,perl有一个-i像sed这样的选项.

  • 你的意思是 *sed* 有像 *perl* 这样的 `-i` 选项,而不是相反。您不会在 POSIX 规范中 *sed* 的必需选项列表中找到 `-i` 选项,顺便说一句,只是偶尔和非正式地在某些供应商端口中找到。阅读:`sed -i` ** 并非普遍支持**,尽管 `perl -i` 是。 (2认同)