如何在不包含目录本身的情况下打开文件和文件夹的目录?
我通常会这样做:
tar -czvf my_directory.tar.gz my_directory
如果我只想在my_directory中包含所有内容(包括隐藏的系统文件),而不是目录本身? 我不想要:
my_directory --- my_file --- my_file --- my_file
我想要:
my_file my_file my_file
cd my_directory/ && tar -zcvf ../my_dir.tgz . && cd ..
应该做一行工作。 它也适用于隐藏文件。 “*”不会通过path名扩展至less在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
使用tar的-C
开关:
tar -czvf my_directory.tar.gz -C my_directory .
-C my_directory
通知tar将当前目录更改为my_directory
,然后.
意思是“添加整个当前目录”(包括隐藏文件和子目录)。
确保在执行之前先执行-C my_directory
.
否则你会得到当前目录中的文件。
您也可以像平常一样创build存档,并将其解压缩到:
tar --strip-components 1 -xvf my_directory.tar.gz
看看--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
转换expression式与sed
类似,我们可以使用除/
(在上面的例子中)以外的分隔符。
https://www.gnu.org/software/tar/manual/html_section/tar_52.html
这个答案应该在大多数情况下工作。 不过请注意,文件名是如何存储在tar文件中的,例如./file1
而不仅仅是file1
。 我发现在使用这个方法来操作用作BuildRoot中的包文件的tarball时,会造成问题。
一个解决scheme是使用一些Bash globs列出除..
之外的所有文件,如下所示:
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*
,所以也可以使用:
shopt -s dotglob cd my_dir tar -zcvf ../my_dir.tar.gz * cd .. shopt -u dotglob
cd my_directory tar zcvf ../my_directory.tar.gz *
TL; DR
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
configuration选项将所有文件移出该目录,但这并不能解决问题.
目录本身。 驯服指挥变得越来越困难。
你可以使用$(find ...)
来为命令添加一个文件列表(如magnus的答案 ),但这可能会导致“文件列表太长”的错误。 最好的办法是把它与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
选项是需要的,所以焦油知道具有相对名称的文件所在的位置。 --no-recursion
标志是这样的,tar不会recursion到被告知要归档的文件夹中(导致重复的文件)。
如果你需要做一些特殊的文件名(过滤,符号链接等), find
命令是非常强大的,你可以通过删除上述命令的tar
部分来testing它:
$ 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'
! -name '*.pdf'
$ find /my/dir/ -printf "%P\n" -type f ! -name '*.pdf' -o -type l -o -type d > textfile.txt > subfolder2 > subfolder > subfolder/.gitignore
非GNU发现
该命令使用printf
(在GNU find
可用),它告诉find
用相对path打印结果。 但是,如果你没有find
GNU,这可以使path相对(使用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 -
我会build议下面的Bash函数(第一个参数是目录的path,第二个参数是生成的归档的基本名称):
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
。 它使用隐藏的(。*)元素和文件名中带有空格的元素。
使用pax。
Pax是一个不推荐使用的软件包,但能够以简单的方式完美地完成这项工作。
pax -w > mydir.tar mydir
如果是Unix / Linux系统,并且您关心隐藏文件(*会被忽略),则需要执行以下操作:
cd my_directory tar zcvf ../my_directory.tar.gz * .??*
我不知道在Windows下隐藏的文件是什么样的。
find $TARGET_DIR -maxdepth 1 -type f -print0 \ | xargs --null --max-args 1 basename --zero \ | tar --create --file=result.tar --directory=$TARGET_DIR --null --files-from=-
假设您不想包含任何子目录或来自任何子目录的任何文件。 安全地处理空格或其他不寻常的字符的文件名。 您可以select在find命令中添加-name '*.sql'
或类似的filter来限制包含的文件。
cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
这个为我工作,它包括所有隐藏的文件,没有把所有的文件放在名为“。”的根目录中。 就像在tomoe的回答中一样 :
最简单的方法,我发现:
cd my_dir && tar -czvf ../my_dir.tar.gz *
tar -cvzf tarlearn.tar.gz --remove-files mytemp/*
如果该文件夹是mytemp,那么如果你应用上面它将压缩和删除文件夹中的所有文件,但保持独立
tar -cvzf tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*
您可以提供排除模式,也可以指定不要查看子文件夹
tar -C my_dir -zcvf my_dir.tar.gz `ls my_dir`