如何使用grep输出作为cd的路径?

如何将grep输出作为参数传递给cd命令?

例如:

 [root@xxx xxx]# pip install django | grep '/usr.*' Requirement already satisfied (use --upgrade to upgrade): django in /usr/lib64/python2.7/site-packages 

这里突出显示/usr/lib64/python2.7/site-packages ,我想将此字符串传递给cd

使用Bash的命令替换 $() ,你还需要-o和grep来只选择匹配的部分:

 cd "$(pip install django | grep -o '/usr.*')" 

请注意,虽然在这种情况下你会逃脱但是你应该总是用双引号括起命令替换,这样shell就不会在空格上执行分词 (默认空格,制表符和换行符,取决于bash情况下的IFS变量) )。

根据您所做的事情以及事先不知道pip将输出的内容,您可能决定使用/usr.*其他内容进行grep

如果你知道目录以/usr开头 (并且它出现在pip的输出行的末尾,并且/usr没有出现在目录名之前的行的任何地方),那么这是一个很好的选择; heemayl的回答告诉你如何。

如果您知道它以/usr开头的原因是您刚刚运行该命令并知道要更改的目录,我建议运行命令cd /usr/lib64/python2.7/site-packages的更简单的解决方案。 即使您不使用制表符,也可以减少输入。

否则,您可能会选择不同的正则表达式,具体取决于您对正在解析的输出的了解。 下面的所有替代方案仍假设目录名称出现在行尾,但其他假设各不相同。

如果你知道目录名是绝对的 (即以/开头) 并且在目录名之前的行上没有/出现 ,你可以使用与heemayl的答案相同的正则表达式,但使用/而不是/usr

 cd "$(pip install django | grep -o '/.*')" 

这匹配/后跟任何字符( . )的零或更多( * )。

如果您知道目录名称不包含水平空格 (没有空格或制表符)并显示在该行的末尾,则可以使用:

 cd "$(pip install django | grep -oP '[^\h]+$')" 

这里我使用了Perl regexp ( -P ),因为\h缩写(对于[:blank:] )使得输入和读取比等效的扩展正则表达式( -E )更容易。 这匹配不是^ )空格或制表符( \h )的字符类( [ ] )中的任何字符的一个或多个( + )。

如果您知道目录名称紧跟在水平空格的前面 (即左侧和右侧用空格填充),并且这是该行中唯一出现的这种情况 ,您可以使用:

 cd "$(pip install django | grep -oP '\hin\h+\K.+')" 

这使用零宽度正向后视断言( \K )来匹配出现在空格或制表符( \h )之后的一个或多个字符( .+ ),以及另一个或多个空格或制表符( \h+ ),实际上没有包括in比赛中的围绕它的空白区域。 查找断言是Perl正则表达式的一个特性。

\h + in\h+\K.+的模式\h + in\h+\K.+也会起作用,但我们只需要在输入之前查找一个空白,无论存在多少空白。 相反,我们必须匹配in之后的所有空格,否则它们不会被\K丢弃,它们将作为目录名称的一部分进行匹配。

如果您知道目录名称后面紧跟着行的最后一次出现,后跟水平空格 ,则可以使用:

 set +H cd "$(pip install django | grep -oP '\hin\h+(?!.*\hin\h.*)\K.*')" set -H 

在那里,零宽度正面后置断言本身包含零宽度负向前瞻断言( (?! ) )。

! 以一种优雅地难以逃脱的方式出现; 我用来阻止它在传递给grep之前触发shell 历史扩展的方法是在运行命令之前暂时禁用历史扩展( set +H )并在之后重新启用它( set -H )。 如果您在脚本中使用此脚本且脚本不包含set -H ,则不需要执行此操作,因为仅当shell以交互方式运行时才会自动启用历史记录扩展。

最后,请注意,这些都没有,也没有heemayl的答案 ,实际上是将grep的输出传递给cd (虽然pip的输出仍然被传送到grep )。 而不是管道 ,这个工作的适当工具是命令替换 。