我通常这样做:
tar -czvf my_directory.tar.gz my_directory
如果我只想在my_directory中包含所有内容(包括任何隐藏的系统文件),而不包括目录本身,该怎么办?我不想:
my_directory
--- my_file
--- my_file
--- my_file
我想要:
my_file
my_file
my_file
我通常这样做:
tar -czvf my_directory.tar.gz my_directory
如果我只想在my_directory中包含所有内容(包括任何隐藏的系统文件),而不包括目录本身,该怎么办?我不想:
my_directory
--- my_file
--- my_file
--- my_file
我想要:
my_file
my_file
my_file
当前回答
TL;DR (no ./和no ./file1!)
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
在某些条件下(只归档文件,dirs和符号链接):
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
解释
不幸的是,下面包含了归档文件中的父目录./:
tar -czf mydir.tgz -C /my/dir .
您可以使用——transform配置选项将所有文件移出该目录,但这不能消除。目录本身。指挥变得越来越难驯服。
您可以使用$(find…)向命令中添加一个文件列表(就像在magnus的answer中一样),但这可能会导致“文件列表太长”错误。最好的方法是将它与tar的-T选项结合起来,就像这样:
find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
基本上,它所做的是列出目录下的所有文件(-type f)、链接(-type l)和子目录(-type d),使用-printf "%P\n"使所有文件名相对,然后将其传递给tar命令(它使用-t -从STDIN获取文件名)。需要使用-C选项,以便tar知道具有相对名称的文件位于何处。——no-recursion标志是为了让tar不会递归到它被告知要归档的文件夹(导致重复文件)。
如果你需要对文件名做一些特殊的事情(过滤,跟踪符号链接等),find命令是非常强大的,你可以通过删除上面命令的tar部分来测试它:
$ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
> textfile.txt
> documentation.pdf
> subfolder2
> subfolder
> subfolder/.gitignore
例如,如果你想过滤PDF文件,添加!- name“* . pdf”
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d
> textfile.txt
> subfolder2
> subfolder
> subfolder/.gitignore
Non-GNU找到
该命令使用printf(在GNU find中可用),它告诉find用相对路径打印结果。然而,如果你没有GNU find,这将使路径相对(用sed删除父类):
find /my/dir/ -type f -o -type l -o -type d | sed s,^/my/dir/,, | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
其他回答
# tar all files within and deeper in a given directory
# with no prefixes ( neither <directory>/ nor ./ )
# parameters: <source directory> <target archive file>
function tar_all_in_dir {
{ cd "$1" && find -type f -print0; } \
| cut --zero-terminated --characters=3- \
| tar --create --file="$2" --directory="$1" --null --files-from=-
}
安全处理包含空格或其他不寻常字符的文件名。您可以选择添加一个名称'*。Sql '或类似于find命令的过滤器来限制包含的文件。
function tar.create() {
local folder="${1}"
local tar="$(basename "${folder}")".tar.gz
cd "${folder}" && tar -zcvf "../${tar}" .; cd - &> /dev/null
}
例子:
tar.create /path/to/folder
不客气
art archive:
# tar -czvf mydir.tar.gz mydir
archive:涂
# tar -xf mydir.tar.gz
这个答案在大多数情况下都适用。但是请注意tar文件中的文件名是如何存储的,例如,./file1而不仅仅是file1。我发现,在使用此方法操作作为BuildRoot包文件的tarball时,这会导致问题。
一种解决方案是使用一些Bash glob列出除..之外的所有文件。是这样的:
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
这是我从这个回答中学到的一个技巧。
现在如果没有文件匹配,tar将返回一个错误。?*或。[^。*,但它仍然可以工作。如果错误是一个问题(你正在检查一个脚本是否成功),这是有效的:
shopt -s nullglob
tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
shopt -u nullglob
虽然现在我们正在处理shell选项,但我们可能会决定使用* match隐藏文件会更整洁:
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
这可能不适用于当前目录下的shell glos *,所以,或者,使用:
shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
使用tar的-C开关:
tar -czvf my_directory.tar.gz -C my_directory .
-C my_directory命令告诉tar将当前目录更改为my_directory,然后。意思是“添加整个当前目录”(包括隐藏文件和子目录)。
确保在执行之前执行-C my_directory。否则,您将获得当前目录中的文件。
警告:你会得到。/file-name格式的条目。Ext而不是file-name.ext!
如果需要file-name形式的条目。然后,阅读其他答案。