Oth*_*eus 6 gnu-screen sed awk text-processing puppet
我需要确定文件是否在某一行包含某个正则表达式,如果找到则返回 true(退出 0),否则返回 false。也许我想得太多了,但事实证明我的尝试有点笨拙。我有一个解决方案,但我正在寻找我没有想到的其他解决方案。我可以使用 perl,但我希望尽可能保持这种“轻量级”,因为它在 puppet 执行周期中运行。
这个问题很常见:在 RHEL6 中,screen 的打包方式将终端宽度限制为 80 个字符,除非您取消注释 132 行。此命令检查该行是否已修复:
awk 'NR==132 && /^#termcapinfo[[:space:]]*xterm Z0=/ {x=1;nextfile} END {exit 1-x}' /etc/screenrc
Run Code Online (Sandbox Code Playgroud)
注意:如果文件少于 132 行,它必须以 false 退出。
我认为sed
在这里会有帮助,但显然你必须做一些奇怪的技巧,比如空替换和分支。尽管如此,我还是希望看到一个 sed 解决方案来学习。也许还有一些我忽略的东西。
编辑 1:添加nextfile
到我的 awk 解决方案中
编辑 2:基准 编辑 3:不同的主机(空闲)。编辑 4:错误地将 Gile 的 awk 时间用于优化运行。编辑 5:新长凳
首先,请注意:wc -l /etc/screenrc
是216
。不存在线路时的 50k 次迭代,以挂墙时间衡量:
Sed 132{p;q}|grep -q ...
解决方案:61.259stail | head | grep -q
: 70.418s 哎哟!head -nX |head -n1|grep -q
:116.9 秒 Brrrrp!谢谢约翰,谢谢 sed!老实说,我很惊讶 perl 在这里是一样的。Perl 在启动时加载了一堆共享库,但只要操作系统缓存它们,它就归结为解析器和字节编码器。在遥远的过去(perl 5.2?)我发现它慢了 20%。Perl 比我最初预期的要慢,但由于我的复制/粘贴错误,它似乎更好。
有实用价值的最大配置文件是/etc/services
. 所以我为这个文件重新运行了这些工作台,要更改的行是文件中的 2/3rds。总行数是 1100,所以我选择了 7220 并相应地修改了正则表达式(这样在一种情况下它会失败,在另一种情况下它会成功;对于工作台它总是失败)。
{head;head}|grep
解决方案:138.341stail|head|grep
解决方案:77.948sJoh*_*024 14
使用 GNU sed:
sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q}; $q1'
Run Code Online (Sandbox Code Playgroud)
132 {/^#termcapinfo[[:space:]]*xterm Z0=/q}
在第 132 行,检查 regex ^#termcapinfo[[:space:]]*xterm Z0=
。如果找到退出,q
则默认退出代码为 0。文件的其余部分将被跳过。
$q1
如果我们到达最后一行,$
则退出并退出代码 1: q1
。
由于没有必要读取文件的第 132 行,因此只要我们到达第 132 行或文件末尾(以先发生者为准),此版本就会退出:
sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q; q1}; $q1'
Run Code Online (Sandbox Code Playgroud)
对于空文件,上面的版本将返回 true。这是因为,如果文件为空,则不执行任何命令并且 sed 以默认退出代码 0 退出。为避免这种情况:
! sed -n '132 {/^#termcapinfo[[:space:]]*xterm Z0=/q1; q}'
Run Code Online (Sandbox Code Playgroud)
这里, sed 命令以代码 0 退出,除非找到所需的字符串,在这种情况下,它以代码 1 退出。 前面的命令!
告诉 shell 反转此代码以返回到我们想要的代码。!
所有 POSIX shell 都支持该修饰符。此版本甚至适用于空文件。(帽子提示:G-Man)
使用 POSIX 工具箱:
tail -n +132 </etc/screenrc | head -n 1 | grep -q pattern
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2396 次 |
最近记录: |