tar中的前缀


17

我目前在shellscript中的效率很低:

cp -a $MYPATH /tmp/$VERSION
cd /tmp
tar cjf archive.tar.bz2 $VERSION

我希望所有内容都包含在名为$ VERSION的目录中-有没有一种方法可以执行此操作而不必像上面的脚本中那样复制所有内容?


为什么要首先复制它?为什么不tar cjf archive.tar.bz2 $MYPATH呢?
Chewie

2
@Chewie他说,他希望将$ version作为存档的父目录。
肯特,

哦,我现在看到了。
Chewie

Answers:


26

GNU版本的tar支持--transform选项(及其别名--xform),您可以像这样使用它

tar --transform "s/^$MYPATH/$VERSION/" -cf archive.tar.bz2 "$MYPATH"

例如,给定此目录树

foo
└── foo.txt

命令

tar --transform "s/^foo/bar/" -cf foo.tar.bz2 foo

将产生一个类似的档案

$ tar -tf foo.tar.bz2
bar/
bar/foo.txt

3
值得注意的是,这种方法可能会破坏符号链接。前置flags=r;解决了stackoverflow.com/a/29661783/388803中提到的问题。
eregon

不要在结尾加上斜线;当我在转换中添加尾部斜杠时,会丢失原始前缀;例如s/^a\//b\//,当其他所有文件都在下面时,tar -t仍然显示; 我认为这很危险,并且我真的不需要保护其他一些文件,这些文件的前缀与tar文件中的目录相同;因此,不要在斜杠后面加上斜杠,我不介意知道处理转换情况的最佳方法,但如果它是根节点的同级节点,则不会。a/b/a/aa/
ThorSummoner


0

如果您可以逃脱而不必在要归档的文件树中保留符号链接,则可以执行

ln -s $MYPATH /tmp/$VERSION
cd /tmp
tar cjhf archive.tar.bz2 $VERSION

h选项意味着取消引用符号链接,即包括链接指向的文件或目录,而不是简单地记录符号链接及其指向的事实。


0

要舒适地添加目录前缀,请使用/--transform参数中不同的分隔符,例如,+,类似Andy的答案。

因此,在更简单的情况下,当前目录中有一堆文件,并且您不想创建tarbomb

tar czf logs_nightly.tar.gz --tranform 's+^+logs_nightly/+' *.log

语法为s+search+replace+,因为^它仅与文件名的开头匹配。

现在,只需回答OP-好吧,您可以/tmp通过运行以下命令避免将整个目录复制到其中:

mv $MYPATH $VERSION
tar cjf archive.tar.bz2 $VERSION
mv $VERSION $MYPATH

或者:

ln $MYPATH $VERSION
tar cjf archive.tar.bz2 $VERSION

(硬链接,避免符号链接出现问题)

出于娱乐价值考虑,包括了最后两个,我本人会坚持toro2k的回答。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.