我正试图在Bundler的锁文件格式中查找BUNDLER VERSION
的值。以下是示例Gemfile.lock
的尾部:
thin
turbolinks (>= 2.5.2)
typogruby
unicorn
xray-rails (>= 0.1.15)
BUNDLED WITH
1.10.4
鉴于上述文件,我想要一个输出1.10.4
的简单bash单行程序。换句话说,比如:
cat Gemfile.lock | [magic here] # => 1.10.4
我希望有一个适用于Mac OS X和常见Linux发行版的解决方案,而无需安装任何特殊工具。
到目前为止,我已经发现我需要这样的正则表达式:
/^BUNDLED WITH\n (\S+)$/
我如何" grep"这个模式的文件只打印捕获组?
我调查sed
并很快感到沮丧。似乎sed不能轻易处理跨越多行的模式。
加成:
较早版本的锁定文件格式没有BUNDLER VERSION
。理想情况下,如果模式不匹配,脚本将输出特殊值。
答案 0 :(得分:2)
这可能适合你(GNU sed):
sed -n '/^BUNDLED WITH/{n;s/\s*//p}' file
在找到所需的字符串后,获取下一行并删除该行前面的空白区域并打印。
答案 1 :(得分:1)
这个解决方案需要Ruby,但是完成了工作:
ruby -e 'puts $<.read[/^BUNDLED WITH\n (\S+)$/, 1] || "NOT FOUND"' Gemfile.lock
答案 2 :(得分:1)
与potong相同的奖金:
sed -n '/^BUNDLED WITH/{n;s/[ \t]*//g;h;};${g;/./!{s/.*/not found/;};p;};' file
细节:
n
选项可以打开静音模式。在此模式下,不再自动显示行,但您可以使用p
命令显式显示行。
/^BUNDLED WITH/ { # condition: if a line starts with "BUNDLED WITH" then:
n; # overwrite the pattern space with the next line
s/[ \t]*//g; # replace all white-spaces with nothing (remove them)
h; # store the pattern space content in the buffer
};
$ { # condition: When the last line is reached then:
g; # replace the pattern space with the buffer content
/./! { # condition: if the pattern space is "empty" then:
s/.*/not found/; # replace the pattern space with "not found"
};
p; # print the pattern space
};
注意:您可以更明确地使用描述版本号的模式(如/./!
或与锚点相同的模式),而不是测试存储的部分是否为空/[0-9][0-9]*\(\.[0-9][0-9]*\)*/!
。 / p>