LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3305|回复: 23

Help: 分解文件名的Bash函数

[复制链接]
发表于 2009-9-11 17:52:42 | 显示全部楼层 |阅读模式
求一个完全用bash内建字串功能分解文件名的函数. 由于效率问题, 最好不要使用grep, gawk等bash外的函数.


一个文件名如下:
./app-sys/bash-test-4.3.3-r1.umk

先去掉开始的路径./app-sys/, 再去掉结尾的.umk
剩下bash-test-4.3.3-r1 放入全局变量$ATOM里.

然后从后往前, 将 -r1 放入全局变量$R里(表示Revision),  $R必定以'-r'开始, 后面跟数字. $R也可能没有, 如
$ATOM为autoconf-2.63

将4.3.3放入全局变量$V里(Version), $V由1个以上的数字组成, 数字间用'.'隔开. $V必须存在.

然后将前面的东东放入$N里(Name). $N可能含有'-', 必须存在.

#parse an package atom. $1 is path name of file.
parse_atom()
{
   ...
}

谢谢
发表于 2009-9-11 20:02:21 | 显示全部楼层
## bash-version is 3.2.39(1)-release
atom()
{
        FILENAME='./app-sys/bash-test-4.3.3-r1.umk'
        ATOM=`basename $FILENAME`
        ATOM="${ATOM%.umk}"
        RR="${ATOM%-r*}"
        R="${ATOM#$RR}"
        V="${RR##*-}"
        N="${RR%$V}"
        export ATOM R V N
        unset RR
######################################
        echo "ATOM=$ATOM"
        echo "RR=$RR"
        echo "R=$R"
        echo "V=$V"
        echo "N=$N"
}
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-11 21:29:11 | 显示全部楼层
非常感谢tomgrean兄.
脚本里一定有你的署名权

我在尝试做一个自己用起来很爽的Linux
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-11 21:36:03 | 显示全部楼层
再征集一个函数, 比较两个ATOM的大小.

$ATOM1:  bash-2.9.umk
$ATOM2:  bash-2.10.umk

$ATOM2 应该大于$ATOM1, 因为10比9大.
所以要根据小数点见数字的个数, 进行补零, 然后比较.

同样的比较也存在于revision中,
如 -r10 要 大于 -r9.  $V的优先级大于$R, 只有$V相同的时候才比较rivision.



参数为2个atom. 如果相等, 返回0. 如果不相等, 返回1, 同时全局变量$rnew 返回较大的ATOM, 全局变量$rold 返回较小的atom.  
rnew意思为 return new,
rold意思为return old

#$1: atom1, $2: atom2
atom_compare()
{
}

非常感谢.
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-11 21:56:52 | 显示全部楼层
另, 稍稍优化一下`basename`, 用bash写个简单的:

# $1 is file name . /good/morning/a.test
# return $rbname
base_name()
{
     local prefix
     prefix=${1%/*}
     rbname=${1#${prefix}/}
}

共同学习, 共同提高
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-12 14:16:14 | 显示全部楼层
关于atom_compare()
应该写三个小的比较函数, 分别比较$N, $V和$R. 再利用tomgrean兄的分解函数, 组合起来就是atom的比较

# $1 是一个版本如 2.6.9
# $2 是另一个版本 2.6.10
# 分解数字和点, 直到剩下空串为止...
compare_version()
{
}


#有了上个函数, 比较rivision就方便多了
compare_revision()
{
}
回复 支持 反对

使用道具 举报

发表于 2009-9-13 03:56:16 | 显示全部楼层
ATOM=`basename $FILENAME`
ATOM="${ATOM%.umk}"
=====================

这两句其实可以合并为一句:

ATOM=`basename $FILENAME .umk`

参见
http://article.phpfans.net/?do=Show&id=MjE4MTI2
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-13 10:33:17 | 显示全部楼层
Post by yzhkpli;2026446
ATOM=`basename $FILENAME`
ATOM="${ATOM%.umk}"
=====================

这两句其实可以合并为一句:

ATOM=`basename $FILENAME .umk`

参见
http://article.phpfans.net/?do=Show&id=MjE4MTI2

正解
base_name也修正如下, 使其保持于basename兼容, 并去除调用另外一个程序的额外时间开销.
  1. #$1 is full path of filename. $2 is suffix.
  2. #$rbname return basename of $1, and remove suffix.
  3. #example:  $1=/sys/test.umk  $2=.umk, $rbname returns test
  4. base_name()
  5. {
  6.           local prefix
  7.           prefix=${1%/*}
  8.           rbname=${1#${prefix}/}
  9.      rbname=${rbname%$2}
  10. }
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-14 23:00:32 | 显示全部楼层
继续求助, 比较Rivision的函数.


  1. # $1 = "-r9", $2 = "-r10"
  2. # "-r10" > "-r9"
  3. # 若$1>$2, 返回 1. 若相等, 返回0. 其他返回2.
  4. compare_revision()
  5. {
  6. }
复制代码


作者有署名权 :help :flash:
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-9-21 09:28:51 | 显示全部楼层
继续求助...
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表