Linux:如何替换文件中包含引号和逗号的文本字符串

时间:2015-09-16 14:46:11

标签: regex bash perl awk sed

我使用awk,perl或sed并不是最好的,我无法弄清楚如何替换文件中的文本字符串。

字符串有点不寻常。实际上,有两个我需要自动替换为1个文件。

该文件包含一行文本,非常长,采用JSON格式。每行替换不会起作用。

这是我需要替换的文字。从:

"minimumVersion":2,"librariesLocation":"libraries","objectsLocation":"objects",

"minimumVersion":2,"librariesLocation":"pack/libraries","objectsLocation":"pack/objects",

正如你所看到的,我需要输入文本和斜线中的引号,以及逗号和库和对象的多次出现,使我对sed,awk和perl的当前知识无用。

如何添加' pack /'文字'图书馆的前缀'和'对象'?

5 个答案:

答案 0 :(得分:3)

请不要尝试使用正则表达式来使用JSON。这很讨厌。使用JSON解析器:

#!/usr/bin/env perl

use strict;
use warnings;
use JSON; 

my $json_str = '{ "minimumVersion":2,"librariesLocation":"libraries","objectsLocation":"objects" }';

my $json_ob = decode_json($json_str);

print "Before:", $json_ob -> {'librariesLocation'},"\n";

#pattern replace just the values we're interested in.
$json_ob -> {'librariesLocation'} =~ s,^,pack/,;
$json_ob -> {'objectsLocation'} =~ s,^,pack/,;

print "After: ", $json_ob -> {'librariesLocation'},"\n";

#print single line text blob
print encode_json($json_ob);
print "\n\n";

## or perhaps (formatted, multiline, whitespace):

print to_json($json_ob, { canonical => 1, pretty => 1 } );

这适用于粗略的样本 - 如果你想要一个更好的样本,给我更多的JSON,我会重新制作。

输出:

Before:libraries
After: pack/libraries
{"objectsLocation":"pack/objects","minimumVersion":2,"librariesLocation":"pack/libraries"}

{
   "librariesLocation" : "pack/libraries",
   "minimumVersion" : 2,
   "objectsLocation" : "pack/objects"
}

编辑:要从文件中执行此操作:

local $/; 
open ( my $input, '<', 'source_filename_here' ) or die $!;
open ( my $output, '>', 'output_filename_here' ) or die $!;

my $json_ob = decode_json(<$input>);
#do the transforms

print {$output} encode_json($json_ob); 

或者(从STDIN打印到STDOUT读取就像sed / grep等):

#!/usr/bin/env perl

use strict;
use warnings;
use JSON;

my @stuff_to_change = qw ( librariesLocation objectsLocation );

local $/;

#read from stdin or arg on commmand line. E.g.:
#myscript.pl somefile
#cat json_file | myscript.pl
my $json_ob = decode_json(<>);

#pattern replace just the values we're interested in.
for my $thing (@stuff_to_change) {
    $json_ob->{$thing} =~ s,^,pack/,;
}

#print single line text blob to STDOUT
print encode_json($json_ob);

答案 1 :(得分:1)

  

如何在文本'libraries'和'objects'中添加'pack /'前缀?

一个简单的<div class="timer md-body-2">{{ countdown }} seconds</div> 命令怎么样:

sed

<强>输出:

echo '"minimumVersion":2,"librariesLocation":"libraries","objectsLocation":"objects",' > file

sed 's~"\(libraries\|objects\)"~"pack/\1"~g' file

运行ssh:

"minimumVersion":2,"librariesLocation":"pack/libraries","objectsLocation":"pack/objects",

答案 2 :(得分:0)

sed --in-place将通过正确的转义

来实现这一目标
$ echo '"minimumVersion":2,"librariesLocation":"libraries","objectsLocation":"objects",' > text.txt      
$ sed --in-place 's/"\(libraries\|objects\)"/"pack\/\1"/g' text.txt
$ cat text.txt 
  "minimumVersion":2,"librariesLocation":"pack/libraries","objectsLocation":"pack/objects",

将模式"libraries"替换为"pack/libraries"(使用匹配模式的分组和重用)

答案 3 :(得分:0)

使用正确的JSON输入,您可以使用jq

$ jq '.librariesLocation |= "pack/"+., .objectsLocation |= "pack/"+.' <<EOF
{"minimumVersion":2,"librariesLocation":"libraries","objectsLocation":"objects"}
EOF
{
  "minimumVersion": 2,
  "librariesLocation": "pack/libraries",
  "objectsLocation": "objects"
}
{
  "minimumVersion": 2,
  "librariesLocation": "libraries",
  "objectsLocation": "pack/objects"
}

如果您的输入只是以逗号分隔的键/值对列表,那么可能能够在过滤之前使用jq将其转换为正确的JSON对象,但是我不知道jq还不知道怎么做。

答案 4 :(得分:0)

awk '{gsub(/libraries",|objects",/, "pack/&")}1' file
minimumVersion":2,"librariesLocation":"pack/libraries","objectsLocation":"pack/objects",