使用 find 仅输出最后一个“/”之后的部分

使用 find 仅输出最后一个“/”之后的部分

此命令:

find ./ -name "mybinaryrpm-1.0.24-1.1.i586.rpm"

给出输出:

./DirectoryName/SubDirectory/mybinaryrpm-1.0.24-1.1.i586.rpm

但我只想要输出:

mybinaryrpm-1.0.24-1.1.i586.rpm

我如何获得它?


我真正想做的是:

  1. 读取包含以行分隔的二进制文件名列表的输入文件
  2. 在当前目录中递归搜索相应名称的文件
  3. 如果找到多个匹配项,则只考虑一个搜索结果并将文件复制到相应的目标目录。

当前代码:

while read line; do
    binaryRpm=$(find ./ -name "$line" -exec basename {} \;)
    echo " [ Read From File: $line ] <==> [ Find Command Searched: $binaryRpm ]"
    ## If found then copy the binary file to dest dir
    ## TODO: If Find Command finds more than One File with the
    ## Same Name, then ONLY ONE FILE MUST be Compared and copied to
    ## the Release Directory
    if [ "$line" != "$binaryRpm" ]; then
        echo "---------- Binary File Searching---------- "
        continue
    else
        echo " !!!!!! Binary File Found ==> $binaryRpm !!!!!! "
    fi
done < "$FILENAME"

答案1

嗯,你的例子实际上没有什么意义,因为正如评论中指出的那样,你想要得到与输入相同的输出。如果你知道输入,那么你已经知道输出了。

但是,一般来说,使用find-printf功能:

find . -name "mybinaryrpm-1.0.24-1.1.i586.rpm" -printf '%f\n'

来自man find,部分-printf

%f    File's name with any leading directories removed (only the last element).

这仅适用于 GNU find,但 GNU 工具是您所要求的 Linux 上的标准。它也可以安装在几乎每个相关平台上。


一个最小的代码示例,可以完成您真正想要做的事情:

#!/bin/sh
FILENAME="/path/to/file/with/filenames"

while read line; do
    binaryRpm=$(find -name "${line}" -type f | head -1)
    if [ -z "${binaryRpm}" ]; then
        echo "No matches found for \"${line}\"."
    else
        echo "Match for \"${line}\" found at \"${binaryRpm}\""
    fi
done < "${FILENAME}"

对我上面的例子的评论:

  • head -1仅保留第一场比赛。
  • [ -z ]检查变量是否为空(如果find上面没有找到任何内容,它将为空)。

对您的脚本的评论:

  • 您不需要检查文件名是否与行匹配,因为find只会返回匹配的行。我猜您会用它来丢弃多个匹配项,但head对于此目的来说,这是一个更好的工具。
  • 您不需要现有的语句,因为脚本无论如何continue都会跳出该if子句并直接迭代循环。for

答案2

尝试这个命令:

find . -name "mybinaryrpm-1.0.24-1.1.i586.rpm" -exec basename {} \;

答案3

为了回答你的问题,你可以尝试这样的方法:

find ./ -name "mybinaryrpm-1.0.24-1.1.i586.rpm" | sed 's|^\..*/\(.*\)|\1|g'

相关内容