我如何将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
。
答案1
答案2
根据您事先所做的事情以及不知道的pip
输出内容,您可能会决定grep
进行其他操作/usr.*
。
如果你知道的话目录以以下内容开头:/usr
(并且它出现在输出行的末尾pip
,并且/usr
没有出现在目录名之前的任何行上),那么这是一个不错的选择;heemayl 的回答告诉你如何。
如果原因你知道它以什么开头/usr
,因为你刚刚运行了命令,并且知道要更改到的目录,我建议使用更简单的解决方案,即运行命令cd /usr/lib64/python2.7/site-packages
。即使你不使用Tab 补全。
否则,您可能会根据对正在解析的输出的了解选择不同的正则表达式。下面的所有替代方案仍然假设目录名称出现在行末,但其他假设有所不同。
如果你知道的话目录名称是绝对的(即以 开头/
)/
目录名前的行中没有出现,你可以使用与heemayl 的回答但/
改为/usr
:
cd "$(pip install django | grep -o '/.*')"
这/
与后跟零个或多个 ( *
) 的任意字符 ( .
) 匹配。
如果你知道的话目录名称不包含水平空格(无空格或制表符)和出现在行尾, 您可以使用:
cd "$(pip install django | grep -oP '[^\h]+$')"
在这里我用的是Perl 正则表达式( -P
),因为\h
缩写 ( [:blank:]
) 比等效的扩展正则表达式 ( ) 更易于输入和阅读-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
其中,零宽度正向后视断言本身包含一个零宽度负向前视断言((?!
)
)。
似乎!
很难逃离优雅地;我用来防止它触发 shell 的方法历史扩展在传递给之前,grep
它会在运行命令之前暂时禁用历史记录扩展 ( set +H
),然后在运行命令之后重新启用它 ( set -H
)。如果您在脚本中使用它并且您的脚本不包含set -H
,则无需执行此操作,因为只有在 shell 以交互方式运行时才会自动启用历史记录扩展。
最后,请注意,这些都不是,也不是heemayl 的回答,实际上是将 的输出通过管道传输grep
到cd
(尽管 的输出pip
仍然通过管道传输到grep
)。而不是管道,适合这项工作的工具是命令替换。