用单引号包装yaml数据

时间:2015-05-30 02:43:11

标签: regex awk sed yaml

我想用单引号包装我的所有YAML数据(在一个大文件中)。我试过了sed,但它不起作用:

sed "s/\(.*: \)\(.*\)/\1'\2'/" <data.yml >datanew.yml

这就是这样的:

location_id: 25
street: 
text: This is text: it contains colons  

并制作如下行:

' location_id: '25
' street: '
' text: This is text: 'it contains colons 

...但我希望它们看起来像:

location_id: '25'
street: ''
text: 'This is text: it contains colons'

这可以在sed(或awkperl或......)中实现吗?根据我的研究,似乎sed可能在拾取第一个冒号时遇到麻烦,因为它与贪婪匹配。我正在运行Ubuntu 14.04。

其他信息

注意YAML具有可选的前导空格,后跟冒号的标记以及该行上的所有其他内容(可能包含一个或多个其他冒号),所有这些都需要用引号括起来。

您可以使用以上三行测试。

更多

谢谢大家的建议。我假设他们中的大多数确实工作,但不适合我。 Here是我终端使用其中一种建议模式的快照。不幸的是,他们都以同样的方式失败了。

更令人沮丧的是,当我在vim中打开文件并运行搜索并使用相同的模式替换时,它完美无缺。我尝试将这种技术用于我的整个文件,但是vim对4M行不满意。

我的sed不知何故?

4 个答案:

答案 0 :(得分:1)

这个正则表达式:

uniforms.scale.value = _canvas.height / 2.0; // TODO: Cache this.

你想做什么。 Working Demo

在Perl中表达最容易。

假设:

^\s*([^:]+)(:\s)(.*?)\s*$

Perl:

$ echo "$tgt"
 location_id: 25
 street: 
 text: This is text: it contains colons  

答案 1 :(得分:0)

你的sed变化不大

sed "s/\([^:]*: \)\(.*\)/\1'\2'/" <data.yml >datanew.yml  

答案 2 :(得分:0)

以下是您可以使用的awk

cat file
Some other data
location_id: 25
street:

awk -v f="'" -F": *" 'NF==2 {$NF=f $NF f}1' file
Some other data
location_id '25'
street ''

它测试行是否有:,如果那么它将'包裹在最后一个字段周围,是否为空。

答案 3 :(得分:0)

以下内容似乎适用于您提供的测试用例,以及我提出的一些案例:

sed "s/\([^:]*:\s*\)\(.*\)/\1'\2'/g"

它的工作方式是对文本进行非贪婪匹配,直到冒号,然后是冒号和可选空格[^:]*:\s*。所有这些都被放入捕获组。我需要“然后跟冒号”的原因是因为文件中出现的某些行如“%YAML 1.1”会匹配正则表达式,即使它们不应该被包括在内。通过添加有冒号的附加约束,这些行将从替换中排除。

下一部分相对简单,只需匹配上一个捕获组之后的任何文本。这可以通过.*(其中还包括冒号,如您在上述问题中提到的那样)来实现。

sed s命令用于替换与第一个捕获组\1匹配的正则表达式,这是第一个冒号和可选空格之前的所有文本,后跟第二个捕获组\2这是冒号和空格后的所有文本,用单引号括起来。

以下是它的演示:

regex test