Regex 非常大的文件上的字符串替换
我有一个巨大的文本文件是JSON。您可以在这里看到:。我已将此JSON保存到名为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的
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"