繁体   English   中英

用命令输出替换字符串,每次都不同

[英]Replace string with output of command, different each time

我有很多文件,我想用UUID替换类名。 我想通了

sed -i -r "s/ Class \w(\w|\d)+/ Class C$(python -c 'import uuid;print(uuid.uuid4().hex)')/"

当模式在每个文件中仅出现一次时,它可以正常工作。 但是,如果模式多次出现,则每次出现都将替换为相同的数字。

Class1.vb

Public Class Class1
    Public ReadOnly Property P As String = "hello"
End Class

Public Class Class2
    Public ReadOnly Property P As String = "hello"
End Class
$ sed -r "s/ Class \w(\w|\d)+/ Class C$(echo $RANDOM)/" Class1.vb
Public Class C27244
        Public ReadOnly Property P As String = "hello"
End Class

Public Class C27244
        Public ReadOnly Property P As String = "hello"
End Class

我希望两个类具有不同的名称。 如何修复我的脚本?

$ awk '{gsub(/Class [[:alnum:]]+/, "Class C" int(9999*rand()))} 1' Class1.vb
Public Class C2377
    Public ReadOnly Property P As String = "hello"
End Class

Public Class C5854
    Public ReadOnly Property P As String = "hello"
End Class

上面的代码会每次给您相同顺序的相同随机数。 如果每次运行该程序都需要不同的随机数,请使用:

awk -v s=$RANDOM 'BEGIN{srand(s)} {gsub(/Class [[:alnum:]]+/, "Class C" int(9999*rand()))} 1' Class1.vb

这个怎么运作

  • gsub(/Class [[:alnum:]]+/, "Class C" int(9999*rand()))

    这将查找正则表达式Class [[:alnum:]]+并用字符串Class C和从int(9999*rand())计算出的四位数随机数的连接替换每个正则表达式。 每行产生一个新的随机数。

  • 1

    这是awk的“打印当前行”的隐喻速记。

GNU sed解决方案更多是作为概念证明而不是严肃的选择。

sed -E -e '/Class \w+/{h;s/.*/bash -c "echo C\\$RANDOM"/;e' \
    -e 'G;s/(.*)\n(.*Class )\w+(.*)/\2\1\3/}' infile

导致

Public Class C24276
    Public ReadOnly Property P As String = "hello"
End Class

Public Class C28554
    Public ReadOnly Property P As String = "hello"
End Class

下面是它的工作原理:

/Class \w+/ {                           # If the line matches "Class <name>"
    h                                   # Copy pattern space to hold space
    s/.*/bash -c "echo C\\$RANDOM"/     # Write Bash command into pattern space
    e                                   # Replace pattern space with command output
    G                                   # Append hold space to pattern space
    s/(.*)\n(.*Class )\w+(.*)/\2\1\3/   # Swap class name with random number
}

备注:

  • 它使用GNU扩展:特别是\\w字符类和e命令。
  • 使用-e将单行代码版本分为两个命令,因为e命令后面不能有任何内容,或者任何内容都可以解释为该命令。
  • 要运行的命令不能只是echo C$RANDOM因为e命令使用sh而不是Bash,并且sh可能没有$RANDOM (例如在Ubuntu上, sh是破折号)。
  • 由于该命令是在双引号中, $$RANDOM已经被转义,因为做的sed前壳第一遍看的命令,是已被转义两次。 或者,我本可以使用

     s/.*/bash -c '\\''echo C$RANDOM'\\''/ 

    用单引号将该命令引起来,但这也不是很容易理解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM