如何使用grep仅获取文件名而不带路径

11

我遇到了以下问题。

我正在执行类似于grep的操作:

$command = grep -r -i --include=*.cfg 'host{' /omd/sites/mesh/etc/icinga/conf.d/objects

我得到了以下输出:

/omd/sites/mesh/etc/icinga/conf.d/objects/testsystem/test1.cfg:define host{
/omd/sites/mesh/etc/icinga/conf.d/objects/testsystem/test2.cfg:define host{
/omd/sites/mesh/etc/icinga/conf.d/objects/testsystem/test3.cfg:define host{
...

对于所有的*.cfg文件。

使用 exec($command,$array)

我将结果放在一个数组中。

是否可能仅获取grep命令的文件名作为结果。

我尝试了以下操作:

$Command=    grep -l -H -r -i --include=*.cfg 'host{' /omd/sites/mesh/etc/icinga/conf.d/objects

但我得到了相同的结果。

我知道在论坛上存在一个类似的主题。(如何在Linux上使用grep仅显示文件名(不显示行匹配项)?),但解决方案不起作用。

我尝试使用"exec($Command,$result_array)"获取带有结果的数组。 提到的解决方案都有效,但我无法用exec()获得结果数组。

有人能帮助我吗?

3个回答

18

另一种更简单的解决方案:

grep -l whatever-you-want | xargs -L 1 basename

或者,如果您没有使用古老版本的GNU coreutils,可以避免使用xargs并改用子shell:

或者,如果您没有使用古老版本的GNU coreutils,可以避免使用xargs,并使用子shell代替。
basename -a $(grep -l whatever-you-want)

basename是在bash中获取不带路径的文件名的简单解决方案。您可能还对dirname感兴趣,以仅获取路径。

GNU Coreutils basename文档


5

使用grep命令,是否可能只获得文件名作为结果。

使用grep命令,您需要使用-l选项来仅显示文件名。

使用find ... -execdir grep ... \{} +命令,您可以防止显示文件的完整路径(这是您需要的吗?)

find /omd/sites/mesh/etc/icinga/conf.d/objects -name '*.cfg' \
     -execdir grep -r -i -l 'host{' \{} +

关于第二个问题的回答

如果你要将一个命令的结果读取到一个数组中,你需要使用以下语法:IFS=$'\n' MYVAR=( $(cmd ...) )

在这种情况下(我将其格式化为多行语句,以清楚地显示该表达式的结构 -- 当然你也可以写成“一行代码”):

IFS=$'\n' MYVAR=(
    $(
        find objects -name '*.cfg' \
                     -execdir grep -r -i -l 'host{' \{} +
    )
)

您可以像往常一样访问数组MYVAR中的结果。在测试时,我发现(在这种情况下有3个匹配项):

sh$ echo ${#MYVAR[@]}
3
sh$ echo ${MYVAR[0]}
./x y.cfg
sh$ echo ${MYVAR[1]}
./d.cfg
sh$ echo ${MYVAR[2]}
./e.cfg
# ...

你提供的字符串可行!谢谢。我还有一个问题: - 我尝试将结果作为数组获取 - 我尝试执行您的字符串如下:$shellCommand=find /omd/sites/mesh/etc/icinga/conf.d/objects -name '*.cfg' \ -execdir grep -r -i -l 'host{' {} + <br />exec($shellCommand, $hostname); - Thomas Lang
1
@ThomasLang 像其他回答者一样,我错过了你问题的第二部分。也许你应该发布_两个_单独的问题?无论如何,我已经修正了我的答案以添加那部分。希望这有所帮助。 - Sylvain Leroux
在第二次查看我的问题时,我发现我忘记了第二部分。因此我后来添加了它。 我希望这不太令人困惑。 - Thomas Lang

0

这应该可以工作:

grep -r -i --include=*.cfg 'host{' /omd/sites/mesh/etc/icinga/conf.d/objects | \
    awk '{print $1}' | sed -e 's|[^/]*/||g' -e 's|:define$||'

awk 部分找到第一个字段,sed 命令修剪路径和 :define


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接