Answers:
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd -
应该一行完成这项工作。它也适用于隐藏文件。至少在bash中,“ *”不会通过路径名扩展来扩展隐藏文件。以下是我的实验:
$ mkdir my_directory
$ touch my_directory/file1
$ touch my_directory/file2
$ touch my_directory/.hiddenfile1
$ touch my_directory/.hiddenfile2
$ cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
$ tar ztf my_dir.tgz
./
./file1
./file2
./.hiddenfile1
./.hiddenfile2
.
为*
,则该命令将按cd my_directory/ && tar -zcvf ../my_dir.tgz * && cd ..
预期运行。
$ (cd my_directory/ && tar -zcvf ../my_dir.tgz .)
cd
进入目录却很la脚。至少可以使用pushd
,popd
如果tar
没有类似的标志-C
。
使用-C
tar 的开关:
tar -czvf my_directory.tar.gz -C my_directory .
该-C my_directory
告诉tar改变当前目录my_directory
,然后.
表示“添加整个当前目录”(包括隐藏文件和子目录)。
确保-C my_directory
先执行操作.
,否则将获得当前目录中的文件。
tar --create --file=foo.tar -C /etc passwd hosts -C /lib libc.a
” apl.jhu.edu/Misc/Unix-info/tar/tar_65.html 我总是尝试tar -czvf my_directory.tar.gz * -C my_directory
并那行不通。-C
位置很重要!该死的焦油...
*
将不包括隐藏文件(这是原始要求)。
看一下--transform
/ --xform
,当文件添加到归档文件时,它使您有机会调整文件名:
% mkdir my_directory
% touch my_directory/file1
% touch my_directory/file2
% touch my_directory/.hiddenfile1
% touch my_directory/.hiddenfile2
% tar -v -c -f my_dir.tgz --xform='s,my_directory/,,' $(find my_directory -type f)
my_directory/file2
my_directory/.hiddenfile1
my_directory/.hiddenfile2
my_directory/file1
% tar -t -f my_dir.tgz
file2
.hiddenfile1
.hiddenfile2
file1
转换表达式类似于的表达式sed
,我们可以使用除/
(,
在上面的示例中)以外的分隔符。
https://www.gnu.org/software/tar/manual/html_section/tar_52.html
--xform
多次传递多个路径。
find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -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 -
不幸的是,以下内容./
在归档文件中包含一个父目录:
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命令(它使用来从STDIN中获取文件名-T -
)。该-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
该命令使用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文件中,例如,./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选项,但我们可能会认为拥有*
匹配的隐藏文件更加巧妙:
shopt -s dotglob
tar -C my_dir -zcvf my_dir.tar.gz *
shopt -u dotglob
这可能无法*
在当前目录中的Shell Glob处起作用,因此,请使用:
shopt -s dotglob
cd my_dir
tar -zcvf ../my_dir.tar.gz *
cd ..
shopt -u dotglob
tar: start.sh: Cannot stat: No such file or directory
此操作时会遇到奇怪的错误,这会发生在当前目录中的所有文件中!如何避免这种情况?
cd my_directory
tar zcvf ../my_directory.tar.gz *
我建议使用以下Bash函数(第一个参数是dir的路径,第二个参数是结果存档的基本名称):
function tar_dir_contents ()
{
local DIRPATH="$1"
local TARARCH="$2.tar.gz"
local ORGIFS="$IFS"
IFS=$'\n'
tar -C "$DIRPATH" -czf "$TARARCH" $( ls -a "$DIRPATH" | grep -v '\(^\.$\)\|\(^\.\.$\)' )
IFS="$ORGIFS"
}
您可以通过以下方式运行它:
$ tar_dir_contents /path/to/some/dir my_archive
它将my_archive.tar.gz
在当前目录中生成存档。它适用于隐藏(。*)元素以及文件名中带有空格的元素。
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
这对我有用,它包含所有隐藏文件,而没有将所有文件放在名为“”的根目录中。就像在tomoe的答案中一样:
这对我有用。
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')
您也可以使用
tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')
在第一个命令中,find返回my_dir的文件和子目录的列表。但是,目录my_dir本身作为“。”包含在该列表中。该-printf参数删除的完整路径,包括“” 还有所有lf 但是,那 空间格式字符串“%P”的printf的叶子中的文件和子目录的列表残余MY_DIR并且可以通过结果的前导空格可以看出查找命令。
对于TAR来说这不是问题,但是如果要解决此问题,请在第二个命令中添加-mindepth 1。
# 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=-
}
安全处理带空格或其他异常字符的文件名。您可以选择-name '*.sql'
向find命令添加一个或类似的过滤器以限制包含的文件。
tar -czf
吗?就我而言,它仅存储文件,而不存储目录。当我只是tar
目录时,它包括它,但tar -czf
仅添加文件。