[原创]tar解压单独文件并且去掉深层路径.doc_VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2862 | 回复: 0   主题: [原创]tar解压单独文件并且去掉深层路径.doc        下一篇 
wulcan
版主
等级:中校
经验:1795
发帖:124
精华:0
注册:2014-3-19
状态:离线
发送短消息息给wulcan 加好友    发送短消息息给wulcan 发消息
发表于: IP:您无权察看 2015-5-26 17:56:13 | [全部帖] [楼主帖] 楼主

直接看示例:

root@listen:/web/test # mkdir -p aa/bb/cc/dd/ee
root@listen:/web/test # touch aa/bb/cc/dd/ee/ff.txt
root@listen:/web/test # tar -cvf test.tar ./*
a ./aa
a ./aa/bb
a ./aa/bb/cc
a ./aa/bb/cc/dd
a ./aa/bb/cc/dd/ee
a ./aa/bb/cc/dd/ee/ff.txt
root@listen:/web/test #


说明:新建一个多层目录aa/bb/cc/dd/ee,然后在里面建一个新文件ff.txt。完成后再对这个目录进行tar打包。

现在的目的是:怎么样只解压出ff.txt,并且存放到当前目录?

为了防止混淆,我们转一个目录,然后把刚才创建的test.tar复制进来:

root@listen:/web/test1 # pwd
/web/test1
root@listen:/web/test1 # ls
test.tar


先来解压看一下,这样得到的路径跟test里面一模一样,然后再删除掉,以便做试验:

root@listen:/web/test1 # tar -xvf test.tar
x ./aa/
x ./aa/bb/
x ./aa/bb/cc/
x ./aa/bb/cc/dd/
x ./aa/bb/cc/dd/ee/
x ./aa/bb/cc/dd/ee/ff.txt
root@listen:/web/test1 # ls
aa              test.tar
root@listen:/web/test1 # ls aa
bb
root@listen:/web/test1 # ls bb
ls: bb: No such file or directory
root@listen:/web/test1 # ls aa/bb/cc/dd/ee/ff.txt
aa/bb/cc/dd/ee/ff.txt
root@listen:/web/test1 # rm -rf aa/


tar除了可以指定tar文件外,还可以有第二个参数,表示“仅解压符合条件的文件”,但是这个参数是一个“pattern”,即“模式”,也就是相当于“正则”,所以注意下面两条命令的区别,特别注意第二条命令,由于前面有个星号(*),所以要加上引号才能正确执行,否则会被shell解释为“通配符”:

root@listen:/web/test1 # tar -xvf test.tar "ff.txt"
tar: ff.txt: Not found in archive
tar: Error exit delayed from previous errors.
root@listen:/web/test1 # tar -xvf test.tar "*/ff.txt"
x ./aa/bb/cc/dd/ee/ff.txt
root@listen:/web/test1 # ls
aa              test.tar


上面的结果显示,这种解压虽然也只解压了指定的文件,但是并没有把多层路径去除,现在我们的目的是:把ff.txt解压到当前/web/test1下面,而不是/web/test1/aa/bb/cc/dd/ee/ff.txt。

tar还提供了一个“替换”模式,这是Linux的gtar没有的功能(也许有,但是百度到的那些的谓的详解里都没找到),就是用-s参数,man里面很长,找最有用的一段:

 -s pattern
Modify file or archive member names according to pattern.  The
pattern has the format /old/new/[ghHprRsS] where old is a basic
regular expression, new is the replacement string of the matched
part, and the optional trailing letters modify how the replace-
ment is handled.  If old is not matched, the pattern is skipped.


摘取重点说,就是模式替换的格式为“/旧名/新名/选项”,旧名新名都支持通配符,至于shell的通配符,在这儿就不展开讲,详细内容可以参照shell的文档。

那我们来规划一个pattern,要把”./bb/cc/dd/’等去掉,old应该为:./.*/,但是放到pattern中就了问题了,因为本身就有斜杠“/”,再写作“/./.*///g”,这种写法是不允许的。
可能你想到了转义,我们来试一下:

root@listen:/web/test1 # tar -xvf test.tar -s "/.\/.*\///g" "*/ff.txt"
tar: Invalid regular expression: trailing backslash (\)


得到了tar的抱怨:不正确的正则表达式:反斜杠错误!

原来反斜杠“\”在pattern中也有其他的含义,所以这路走不通了。

顺便说一下,上面用的规则:第一块old部分已经了解,第二块new部分是一个空串,实际效果就是删除掉,在这块中可以用\1,\2来代表前面小括号内的部分,这跟正则一样。同时,你也看到反斜杠的用途了。

那怎么办呢?

bsd里还有个不成文的规定:模式的分界符还可以用其他字符代替,我们可以用冒号来代替斜杠“/”

root@listen:/web/test1 # tar -xvf test.tar -s ":./.*/::g" "*/ff.txt"
x ff.txt
root@listen:/web/test1 # ls
aa              ff.txt          test.tar


怎么样?解压出单独文件ff.txt了吧!

还可以换成其他的分界符:

root@listen:/web/test1 # tar -xvf test.tar -s ",./.*/,,g" "*/ff.txt"
x ff.txt
root@listen:/web/test1 # tar -xvf test.tar -s ">./.*/>>g" "*/ff.txt"
x ff.txt
root@listen:/web/test1 # tar -xvf test.tar -s "@./.*/@@g" "*/ff.txt"
x ff.txt
root@listen:/web/test1 # tar -xvf test.tar -s "|./.*/||g" "*/ff.txt"
x ff.txt


有时是需要临时发挥的。

这样做有什么实际用处呢?比如我有一个系统的打包备份,有上万个文件,一天误删除了一个文件,想从这个包里面取出一个文件,如果都解开比较麻烦,而这个的路径又比较深,找起来挺麻烦,就可以利用这个命令把这个文件方便地取出来。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论