[英]Remove $PATH entry based on regex
我正在尝试删除$ PATH中的条目,如果该条目包含给定的字符串foo
。 例如PATH=/home/me/bin:/home/foo/bin:/usr/foo/bin:/bin
将成为PATH=/home/me/bin:/bin
。 我目前有
echo $PATH | perl -pe 's/:(.*?)foo(.*?):/:/g'
但这似乎删除了太多条目,即使我尝试使用非贪婪匹配也是如此。 我究竟做错了什么?
我将分割字符串,选择有效部分,然后再次加入字符串:
perl -e 'print join ":", grep !/foo/, split ":", $ENV{PATH}'
您可以使用:
perl -pe 's/:(.*?)foo[^:]*(?=:|$)//g' <<< "$PATH"
/home/me/bin:/bin
您还可以使用awk
遍历路径,仅打印不包含foo
的路径:
awk -F: '{for (i=1; i<=NF; i++) if ($i !~ /foo/) {printf "%s%s", $i, (i==NF? RS : FS)}}'
-F:
设置:
作为字段分隔符。 for (i=1; i<=NF; i++)
遍历字段。 if ($i !~ /foo/)
如果路径中不包含字符串foo
,则执行下一个操作: printf "%s%s", $i, (i==NF? RS : FS)
打印行,以新行或:
结尾,具体取决于它所在的位置。 如果是最后一个字段,则换行; 否则:
。 $ cat a
/home/me/bin:/home/foo/bin:/usr/foo/bin:/bin
/home/me/bin:/home/fio/bin:/usr/foo/bin:/bin
$ awk -F: '{for (i=1; i<=NF; i++) if ($i !~ /foo/) {printf "%s%s", $i, (i==NF? RS : FS)}}' a
/home/me/bin:/bin
/home/me/bin:/home/fio/bin:/bin
我开始构建一个正则表达式,它可以处理任一端的所有冒号组合,但是它变得很快。 但是由于您使用的是Perl(顺便说一句,顺便说一句),像这样的事情如何:
perl -e 'print join(":", grep { $_ !~ m/foo/ } split( ":", '"$PATH"' ) );'
使用非贪婪匹配.*?
对您有好处.*?
在下面的正则表达式中。
echo $PATH | perl -pe 's/:(.*?)foo(.*?):/:/g'
但是,您的正则表达式存在缺陷,因为您没有限制允许的字符,因此可以跨越冒号边界捕获。
这就是为什么split
是一个很好的工具的原因。 它不仅强制执行边界,还强制执行边界之间的可接受字符。
当然,可以使用正则表达式来执行此操作,就像您想要的那样:
echo $PATH | perl -pe 's/[^:=]*foo[^:]*:?//g'
如果是最后一个条目,则上面将留下一个冒号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.