通常,我会执行以下操作:
cat >> ~/.bashrc <<EOF
export PATH=~/.composer/vendor/bin:$PATH
EOF
也可以通过ansible(
line
+ insertafter=EOF
+ regexp
)来做到这一点,但这是另一回事了。做类似的事情:ex +'$s@$@\rexport PATH=\~/.composer/vendor/bin:$PATH@' -cwq ~/.bashrc
,但是理想情况下如何检查行是否已经存在(因此什么也不做)而不重复同一行?
或者也许在Ex编辑器中有一些更简单的方法?
#1 楼
如果您想要防弹,可能需要比上面复杂的选项更轻便的东西。我会坚持使用ex
的POSIX功能,使其变得愚蠢简单:只要删除该行(不管它存在多少次),就将其添加到文件末尾,然后保存并退出: ex -sc 'g/^export PATH=\~\/\.composer\/vendor\/bin:$PATH$/d
$a
export PATH=~/.composer/vendor/bin:$PATH
.
x' ~/.bashrc
我锚定了正则表达式以增强鲁棒性,尽管我认为偶然匹配此正则表达式几乎是不可能的。 (锚定的意思是使用
^
和$
,因此仅当正则表达式与整行匹配时才匹配。) 。还有许多其他简单的方法可以做到这一点。例如,将行添加到文件的末尾,然后通过外部UNIX过滤器运行文件的最后两行
+cmd
:ex -sc '$a
export PATH=~/.composer/vendor/bin:$PATH
.
$-,$!uniq
x' input
这非常非常简洁明了,并且完全兼容POSIX。它使用
-c
的Escape功能进行外部文本过滤,并使用POSIX指定的shell实用程序uniq
最重要的是,
ex
设计用于就地文件编辑,是迄今为止最便携的以非交互方式完成此任务的方式。实际上,它甚至早于原始的uniq
-名称ex
代表“视觉编辑器”,而基于它的非视觉编辑器是vi
。并将其简化为一行),请使用vi
将命令发送到ex
:printf %s\n '$a' 'export PATH=~/.composer/vendor/bin:$PATH' . '$-,$!uniq' x | ex input
评论
相关:vi.stackexchange.com/q/6269/4676
–通配符
19年7月17日在2:29
#2 楼
一个可能的解决方案是创建一个函数来执行此操作:首先,我们创建一个局部变量l:res
,该变量将用于计算该行的出现次数。 我们使用
global
命令:每次匹配行时,l:res
都会递增。文件,因此我们要感谢l:res
到最后一行,并使用G
创建新行,并在其中添加要添加的行。注1我用来设置
o
值的方法是有点沉重,可以用@Alex在他的答案中建议的内容替换为以下内容:使用参数:function! AddLine()
let l:res = 0
g/export PATH=\~\/.composer\/vendor\/bin:\$PATH/let l:res = l:res+1
if (l:res == 0)
normal G
normal oexport PATH=~/.composer/vendor/bin:$PATH
endif
endfunction
请注意
l:res
的技巧,在字符前面添加escape()
可能会导致搜索问题。 > 请注意,我仍然需要在调用函数时自行转义
\
(我没有设法自动转义\
):let l:res = search('export PATH=\~\/.composer\/vendor\/bin:\$PATH')
#3 楼
尝试:ex ~/.bashrc -c "if search('export PATH=\~\/.composer\/vendor\/bin:$PATH')>0 | norm quit | endif | norm Aexport PATH=~/.composer/vendor/bin:$PATH"
请注意,
:append
不能在if endif
-block的Ex模式下工作(请参阅VimDoc),因此我必须将norm A...
放在外面。#4 楼
我通常使用:perl -i -p0e '$_.="export PATH=~/bin:$PATH\n" unless m!~/bin:!' ~/.bashrc
#5 楼
为了简化并避免出现许多\
,要添加的行将是export PATH=mybin:PATH
。主要策略:用text + mybin-path替换“ non-
mybin
”文本(所有文件) -定义: vim +'s#\v%^((.|\n)(mybin:)@!)*%$#&\rexport PATH=mybin:PATH#e' -cx bashrc
,或者具有更多的教学缩进:
s# substitute
\v very magical to redude \
%^ file begin
((.|\n)(mybin:)@!)* multi-line str without "mybin:"
(any char not followed by "mybin")*
%$ end of file
# by
如果有匹配项:
&
具有bashrc
的全文,并且&
不包含/mybin:/
so:
# by ...
& all file
export PATH=mybin:PATH and the new path
#e don't complain if patt not found
-cx save and leave
更新:最后,我们可以制作一个vim脚本:
$ cat bashrcfix
#!/usr/bin/vim -s
:e ~/fakebashrc
:s#\v%^((.|\n)(mybin:)@!)*%$#&\rexport PATH=mybin:PATH#e
:x
chmod 755并安装它。用法:
bashrcfix
注意:在
\v
模式下,=
表示可选#6 楼
这些答案中的大多数似乎对复杂的旧shell命令来说很复杂: >编辑:grep的退出代码很重要,在这种情况下,需要使用
! grep
反转该代码;在这种情况下,grep -v
将不会退出。谢谢@joeytwiddle的提示。评论
我认为grep -v不会为您提供所需的退出代码。但是! grep应该这样做。
– joeytwiddle
15年10月4日,11:39
如果是这种情况,那么您甚至不需要-v就可以了!
– Sukima
2015年10月4日13:37
究竟。您可以编辑答案以进行更正。
– joeytwiddle
2015年10月4日在20:23
1.您应该使用-F,以便grep不会将字符解释为正则表达式,并且2.使用-q而不是重定向至/ dev / null。请参阅我先前对问题的评论。
–muru
2015年10月6日22:06
好点。好奇-q和-F选项的可移植性如何?我认为> / dev / null在不同平台之间更为通用(sun vs hp vs Mac OS X vs Ubuntu vs FreeBSD vs…)
– Sukima
2015年10月7日在21:46
评论
您不能外包吗? grep -Fq'导出PATH =〜/ .composer / vendor / bin:$ PATH'〜/ .bashrc ||前...(或猫)?我相信这可能类似于此方法,但相反(当字符串不存在时,请执行某些操作)。
例如〜/ .bashrc -c“ if search('export PATH = \〜\ /。composer \ / vendor \ / bin:\ $ PATH')> 0 | norm quit | endif | norm Aexport PATH =〜/ .composer /供应商/ bin:$ PATH“
请注意,export是命令,因此该行的其余部分是一个shell单词,而不是赋值。因此,与使用变量赋值(不使用导出)不同,您需要双引号,否则它将在空白处中断。另请参阅如何正确地将路径添加到PATH。
我找到了昨天我一直在寻找的实际链接(尽管以上链接也很好)。局部变量赋值是否需要引号?