- 论坛徽章:
- 0
|
手头上遇到的一个小需求,觉得有点意思,分享下,抛砖以引玉
软件包的文件复制时,排除指定目录
需求: 在 Linux 系统中,将已安装的软件包中的文件列表中复制到另外目录中。
但要排除指定的目录,即此指定的目录不需要复制。
如
glibc 包中有
f: /etc/nscd.conf
d: /usr/
d: /usr/bin/
f: /usr/bin/catchsegv
f: /usr/include/_G_config.h
f: /usr/include/a.out.h
指定排除 /usr/share/doc /usr/include 两个目录
那么,上述列表中只复制以下两个
f: /etc/nscd.conf
f: /usr/bin/catchsegv
用户提供的排除目录,末尾的可能有带 '/', 也可能不带,也有可能写在同一行,或分成多行,如:
/usr/share/man/ /tmp/
/usr/include
文件列表则由包安装管理器自行检索得到,一般是一项一行
试了挺久,主要是路径前缀不知道如何匹配,
如文件: /usr/sharefoo 不能被 /usr/share 的写法给截了
如果要排除 /usr/ /usr/share 两个目录, 那么 /usr/share/{man,doc,themes,locale}/* 等目录
及其下全部分内容都属于排除的范围。
coreutils 包有个 /usr/bin/[ 文件,让 grep 遇到,可能就犯傻了。
以下是有 awk 的实现
- echo "$EXDIR , $PKGFILES" | awk '
- BEGIN {
- met_sep = 0
- }
- {
- for (i = 1; i <= NF; ++i)
- {
- if ( $i == ",")
- {
- met_sep = 1
- continue
- }
- if (met_sep == 0)
- {
- ed[$i] = 1
- }
- else
- {
- pf[$i] = 1
- }
- }
- }
- END {
- prd = ""
- for (i in pf)
- {
- is_needed = 1
- for (j in ed)
- {
- sub("/$", "", j)
- left_str = gensub(j, "", 1, i)
- if (left_str == i)
- continue
- if (length(left_str) == 0 || match(left_str, "^/"))
- {
- is_needed = 0
- break
- }
- }
- if (is_needed == 1)
- prd = prd " " i
- }
- print prd
- }'
复制代码 |
|