Regex 非常大的文件上的字符串替换

Regex 非常大的文件上的字符串替换,regex,bash,vim,sed,Regex,Bash,Vim,Sed,我有一个巨大的文本文件是JSON。您可以在这里看到:。我已将此JSON保存到名为cards.JSON的文件中 在cards.json中,我需要用反斜杠\转义每个引号' 所以我需要用\'替换' 通常这在任何编辑器中都是微不足道的,但是文件太大了如何转义此字符串中的所有单引号? 我所尝试的: 我尝试使用sed。我的命令是sed s/\'/\\\'/cards.json>cards\u cleaned.json。但是cards_cleaned.json文件没有任何转义的,,它只是cards.json的

我有一个巨大的文本文件是JSON。您可以在这里看到:。我已将此JSON保存到名为
cards.JSON
的文件中

cards.json
中,我需要用反斜杠
\
转义每个引号
'

所以我需要用
\'
替换
'

通常这在任何编辑器中都是微不足道的,但是文件太大了如何转义此字符串中的所有单引号?

我所尝试的:

  • 我尝试使用
    sed
    。我的命令是
    sed s/\'/\\\'/cards.json>cards\u cleaned.json
    。但是cards_cleaned.json文件没有任何转义的
    ,它只是
    cards.json的一个精确副本。Sed在我执行
    Sed s/\'/foobar/cards.json>cards\u cleaned.json
    时工作,因此我假设我的转义反斜杠有问题

  • 我尝试使用
    vim
    。我在vim
    $vi cards.json中打开了cards.json。然后我尝试使用
    :%s/'/\'/g
    替换全局字符串。这并没有改变文件中的任何内容


  • 在Vi中,需要转义\字符

    试用

    :%s/'/\\'/g
    
    对我来说,它奏效了

    Test.txt

    \'\'\'\'\'\''

    • 不需要在搜索模式中第一次转义
      \'
    • 您应该用双引号包围(如果单引号不是要更改的字符,则为单引号),并由于在本例中的shell级别使用了双引号而转义

    您需要双倍逃逸背部,因此请使用:

    sed -i.bak "s/'/\\\\'/g" cards.json
    

    您需要在shell中使用双引号来避免引用单引号字符,但是您必须小心,因为对于双引号字符串,shell使用反斜杠作为引号字符

    $ echo "eoieriou'iouou'oiuiouiuo"|sed "s/'/\\'/g"
    eoieriou'iouou'oiuiouiuo
    
    sed
    试图执行的命令是
    s/'/\'/g
    ,但是
    sed
    引用字符是反斜杠,因此可以用一个引号替换每个引号

    当它到达
    sed
    时,我们也必须引用反斜杠,所以让我们试试看

    $ echo "eoieriou'iouou'oiuiouiuo"|sed "s/'/\\\\'/g"  # Four (4) backslashes in a row
    eoieriou\'iouou\'oiuiouiuo
    $ 
    
    没关系,不是吗?因为
    sed
    被指示执行
    s/'/\\\'/g
    ,所以从
    sed
    的POV中引用的字符本身就是反斜杠


    请注意,单引号或双引号不是来自
    sed
    的POV的特殊字符,它们仅在shell上下文中是特殊的。

    您可以在vim中这样使用

     :%s/'/\\\'/g
    
    在sed中

     sed "s/'/\\\'/g" filename
    

    这是一个
    awk
    版本:

    cat file
    hi'more data here'
    
    或者,如果需要双反斜杠:

    awk '{gsub(g,"\\\\"g)}1' g="'" file
    hi\\'more data here\\'
    

    尽管@anubhava或@gboffi的答案有效,但它们产生了无效的JSON

    反斜杠后有几个字符

    \"
    \\
    \/
    \b
    \f
    \n
    \r
    \t
    \u four-hex-digits
    
    e、 g.以下原始(正确)JSON的一部分

    你想得到什么

    [
       {
          "description" : "Whenever a land enters the battlefield, Ankh of Mishra deals 2 damage to that land\'s controller.",
          "rarity" : "Rare",
          "name" : "Ankh of Mishra"
       }
    ]
    #e.g. instead of the land's want land\'s
    
    但这是一个无效的JSON

    因此,如果您(出于某种奇怪的原因)想要使用
    反斜杠,则需要使用double
    \\
    ,例如:

    [
       {
          "description" : "Whenever a land enters the battlefield, Ankh of Mishra deals 2 damage to that land\\'s controller.",
          "rarity" : "Rare",
          "name" : "Ankh of Mishra"
       }
    ]
    
    解决方案(两者都适用) 使用
    perl

    perl -pE "s/'/\\\'/g" < mtg_cards.json > cards.malformed.json
    #changes "land's" to wrong "land\'s"
    
    perl-pE“s/'/\'/g”cards.malformed.json
    #将“土地”更改为错误的“土地”
    

    perl-pE“s/'/\'/g”card\u with\u double\u BS.json
    #将“土地”更改为“土地\\s”
    

    Ps:因为您的文件只有一个长(30MB)行,
    vim
    有一些问题。您可以在编辑之前漂亮地打印(折叠和缩进)JSON。这里有很多工具,我使用perl包中的
    json_xs
    命令。“预处理”后,您可以安全地使用
    vim

    这在测试中有效,但vim永远无法完成操作。然后,您可以对sed使用不同的分隔符:cat cards.json | sed“s_u'./g”>cards.json,因此,我想它可能会遇到与我所演示的相同的问题…
    $echo“eoieriou'iouou'oiuiouo”\124; sed“s/'/\\&'/g”
    返回
    eoieriou&iouou&oiuiouo
    ,因为执行的
    sed
    命令是
    s/'/\&/g
    (请注意,我没有投反对票,但你可以在发布前测试你的答案,不是吗?@GBOFI event如果你没有投反对票,你的回复是值得的(我对你的评论投赞成票)。我适应双重转义,我尽量避免使用
    &
    它也与三个“\”一起工作:
    sed-I.bak“s/'/\\\'/g”cards.json
    @Jotne是的,它是有效的,但我很难向我解释它为什么有效…,我想知道您是否愿意解释它为什么在单独的answer@gboffi我不知道为什么,只是测试了一下。没有错误,输出正确。@Jotne当序列
    \'
    是双q时,shell对它的解释似乎不同uoted,如
    $echo\'“\'”中的
    产生以下输出:
    '\'
    ---我仍然需要找到真正的解释…也许改天吧,但如果OP PAR通过另一个程序来解决这个问题,并且一个转义帮助,因为它在过程中被删除并保留了单引号呢?@Jotne-投机。无论如何,(如你所见)我为两者都提供了一个解决方案。是的,这是纯粹的推测。这只是对无效Json的一个注释。只要OP不评论什么是有效的,我们就必须拭目以待。我可能是OP要求一个斜杠而不是两个斜杠的原因。@jm666您的评论是明智的,但正如jotne所言,您不能自己推测文件的目的地。(+1代表你们两个)@NeronLeVelu,因此我在我的原始答案中包含了两种情况的解决方案,现在将其编辑为粗体(当然)。:)为什么需要一个反斜杠?正如您在jm666帖子中看到的,这给出了无效的json代码。
    [
       {
          "description" : "Whenever a land enters the battlefield, Ankh of Mishra deals 2 damage to that land\'s controller.",
          "rarity" : "Rare",
          "name" : "Ankh of Mishra"
       }
    ]
    #e.g. instead of the land's want land\'s
    
    [
       {
          "description" : "Whenever a land enters the battlefield, Ankh of Mishra deals 2 damage to that land\\'s controller.",
          "rarity" : "Rare",
          "name" : "Ankh of Mishra"
       }
    ]
    
    perl -pE "s/'/\\\'/g" < mtg_cards.json > cards.malformed.json
    #changes "land's" to wrong "land\'s"
    
    perl -pE "s/'/\\\\'/g" < mtg_cards.json > card_with_double_BS.json
    #changes "land's" to "land\\s"