Answers:
根据您所做的事情和事先不知道pip
将输出的内容,您可能会决定使用grep
而不是/usr.*
。
如果您知道目录以/usr
(以开头,并且出现在的输出行的末尾pip
,并且/usr
未出现在目录名之前的行的任何地方),那么这是一个不错的选择;heemayl的答案告诉您如何。
如果您知道它开始的原因/usr
是您刚刚运行了命令并知道了要更改的目录,那么建议您使用运行命令的更简单的解决方案cd /usr/lib64/python2.7/site-packages
。即使您不使用制表符补全,也可以减少打字。
否则,您可以根据对所解析的输出的了解来选择其他正则表达式。下面的所有替代方案仍假定目录名称显示在该行的末尾,但其他假设有所不同。
如果您知道目录名称是绝对的(即以开头/
),并且/
目录名称之前的行中没有出现,则可以使用与heemayl的答案相同的regexp,但可以使用/
代替/usr
:
cd "$(pip install django | grep -o '/.*')"
这与/
后跟零个或多个(*
)的任何字符(.
)相匹配。
如果您知道目录名不包含水平空格(没有空格或制表符)并且出现在行的末尾,则可以使用:
cd "$(pip install django | grep -oP '[^\h]+$')"
在这里,我使用了Perl regexp(-P
),因为\h
缩写(for [:blank:]
)使它的输入和阅读比等效的扩展regexp(-E
)更容易。这会与非()空格或制表符()的+
一类字符([
]
)中的任何一个或多个字符()相匹配。^
\h
如果您知道目录名前面紧跟in
着水平空白(即在左右两侧都用空格填充),并且这是该行中唯一的这种情况,in
则可以使用:
cd "$(pip install django | grep -oP '\hin\h+\K.+')"
它使用零宽度正向后断言(\K
)来匹配.+
在空格或制表符(\h
)之后出现的一个或多个字符()in
和另一个或多个空格或制表符(\h+
)之后出现的字符,而不实际包含in
和空格在比赛中将其包围。环顾断言是Perl正则表达式的功能。
该模式也可以使用,但是无论存在多少,我们都只需要在前面查找一个空格即可。相反,我们必须匹配之后的所有空格,否则它们将不会被丢弃,并且会作为目录名称的一部分进行匹配。\h+in\h+\K.+
in
in
\K
如果您知道目录名紧跟在行的最后一次出现之后,in
然后是水平空格,则可以使用:
set +H
cd "$(pip install django | grep -oP '\hin\h+(?!.*\hin\h.*)\K.*')"
set -H
在这里,零宽度的正向后断言本身包含一个零宽度的负向前断言((?!
)
)。
在!
以这样的方式为可出现难以逃脱优雅; 我用来阻止它在传递给它之前触发外壳程序历史记录扩展的方法grep
是set +H
在运行命令之前暂时禁用历史记录扩展(),然后重新启用它(set -H
)。如果您在脚本中使用此脚本,而您的脚本中不包含set -H
,则不需要这样做,因为仅当shell交互式运行时,历史记录扩展才会自动启用。
最后,需要注意的是没有这些,也不heemayl的回答,实际上是管道输出grep
到cd
(虽然输出pip
仍然被输送到grep
)。而不是管道,这份工作的合适的工具是命令替换。
` and
``,并且您在grep表达式周围使用了单引号。
!
没有用-引号'
引起来,因为- '
引号本身也是用引号引起的。该命令的复杂性使其很容易错误地预测其效果,但是显然由于扩展顺序(!
较早),它最终的工作方式类似于x=foo; echo "'$x'"
(-> 'foo'
)。除去外部"
引号将导致!
被'
引号并阻止历史记录扩展,但是cd
如果目录名称中包含空格,则失败。