有这个:
$ls $des/bin
a.c analysis.hpp classify.hpp main.cpp split.hpp
a.cpp a.out grade.cpp main.out student.cpp
analysis.cpp classify.cpp grade.hpp split.cpp student.hpp
$ for i in $des/bin/*{hpp,cpp}; do echo $i; done | tar czvf files.tar.gz -C $des/bin -T -
/home/user/Desktop/bin/analysis.hpp
/home/user/Desktop/bin/classify.hpp
/home/user/Desktop/bin/grade.hpp
/home/user/Desktop/bin/split.hpp
/home/user/Desktop/bin/student.hpp
/home/user/Desktop/bin/a.cpp
/home/user/Desktop/bin/analysis.cpp
/home/user/Desktop/bin/classify.cpp
/home/user/Desktop/bin/grade.cpp
/home/user/Desktop/bin/main.cpp
/home/user/Desktop/bin/split.cpp
/home/user/Desktop/bin/student.cpp
现在 -> 即便如此,我也有改变了到 dir $des/bin
,它仍然给出从 root 开始的绝对路径,但它应该给出相对的从当前目录开始的路径(在$des/bin
后面-C
),为什么?
答案1
由于$des
contains /home/user/Desktop
,您要传递到的文件列表tar -T -
是:
/home/user/Desktop/bin/analysis.hpp
/home/user/Desktop/bin/classify.hpp
/home/user/Desktop/bin/grade.hpp
[...]
您需要该列表为:
analysis.hpp
classify.hpp
grade.hpp
[...]
如果这是您想要存储在存档中的路径。
通常,您会这样做:
(
cd -P -- "$des/bin" &&
printf '%s\0' *.[hc]pp |
tar --null -T - -zcvf -
) > file.tar.gz
(假设 GNUtar
或兼容)。
如果文件列表足够小,则不需要printf
.你可以这样做:
(
cd -P -- "$des/bin" &&
tar -czvf - -- *.[hc]pp
) > file.tar.gz
或者压缩为最短的形式:
(cd -P -- "$des/bin"&&tar czvf - -- *.[hc]pp)>file.tar.gz
如果文件数量非常大*.[hc]pp
,则可能会超出系统调用可以采用的 cmdline+environ 的最大大小execve()
。printf
在 shell 中使用printf
内置函数可以bash
解决这个问题,因为内置函数不是通过execve()
系统调用执行的,因此不受该限制的影响。
答案2
仅限 GNU tar
tar --transform "s,.*/\(.*\),$des/bin/\1," -czf ~/files.tar.gz "$des"/bin/*.[ch]pp
可能是您正在寻找的内容(其中第一个$des/bin/
可以替换为您喜欢的任何内容并\1
代表文件名)
tar --transform 's,.*/\(.*\),\1,' -czf ~/files.tar.gz "$des"/bin/*.[ch]pp