此命令:
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
我如何获得它?
我真正想做的是:
- 读取包含以行分隔的二进制文件名列表的输入文件
- 在当前目录中递归搜索相应名称的文件
- 如果找到多个匹配项,则只考虑一个搜索结果并将文件复制到相应的目标目录。
当前代码:
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'