【发布时间】:2011-01-19 05:25:12
【问题描述】:
一个非常基本的问题,但我似乎无法在 stackoverflow 或在线其他地方找到真正解决问题的答案。
我正在编写一个简单的 bash 脚本来批处理一堆文件。该脚本由目录列表提供,然后单独处理它们。不幸的是,每个文件名的格式可能会有所不同,这就是我遇到麻烦的地方。下面是我正在使用的文件名类型和正在使用的脚本的示例。
附:我确信也可能有某种方法可以使用 awk(或任何数量的 unix 工具,但现在我专注于 sed)。
提前致谢:
文件:
/home/acct/Foo-Bar.fl
/home/acct/Foo-1.1.fl
/home/acct/Cat-3.4-500.fl
/home/acct/DOG-BEAR-4.4-1.1.fl
/home/acct/DOG-BEAR-4.4-UPDATED.fl
我正在尝试从每一行中提取完整路径、文件名、版本号和文件前缀。以下是我最近的尝试:
DIR_PATH="/home/acct/
for i in `find ${DIR_PATH}`;
do
FILEPATH="$i"
FILENAME=`echo $i | sed -e "s#${DIR_PATH}##g"`
FILEPREFIX=`echo $FILENAME | sed -e "s/\(.*\)-[0-9]\+.*/\1/g"`
FILEVERSION=`echo $FILENAME | sed -e "s/.*-\([0-9]\+.*\)\.fl/\1/g`
echo "$DIR_PATH"
echo "$FILE_PATH"
echo "$FILENAME"
echo "$FILEPREFIX"
echo "$FILEVERSION"
#do something with this file now that I know what is going on with it
done
在处理以“破折号”分隔的版本号和没有版本号的文件时,问题就来了。我想我已经解决了复杂版本号的所有问题,但仍在努力解决根本不存在版本号的情况。
我想我需要做一些 or 或 type 表达式(或者有第二个 sed 语句来做另一遍),但我不确定如何格式化它。
更新:
根据 Axel 的评论,通过使用 basename 而不是尝试匹配路径,可以更轻松地确定文件名。此外,下面的答案涉及将文件名与扩展名分开,这也是我认为值得纳入的更改。
我会将脚本更新为类似于以下内容的更改:
FILEPATH="$i"
FILENAME=`basename $i`
FILENAMENOSUFFIX=`echo $FILENAME | sed -e "s/\(.*\)\..*/\1/g"`
FILEPREFIX=`echo $FILENAME | sed -e "s/\(.*\)-[0-9]\+.*/\1/g"`
【问题讨论】:
-
有些人在遇到问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。 ——杰米·扎温斯基
-
至少对于文件名,您应该使用 FILENAME=
basename $i。它可以正常工作(即使名称包含哈希“#”... -
Axel,这很好(之前没有使用过 basename)。这是从文件名中剥离目录信息的一种更好的技术。重大帮助!
-
@Joey: Obligatory xkcd link