首页 文章

如何在不包含目录本身的情况下tar文件和文件夹目录?

提问于
浏览
304

我通常这样做:

tar -czvf my_directory.tar.gz my_directory

如果我只想在my_directory中包含所有内容(包括任何隐藏的系统文件),而不是目录本身,该怎么办?我不想要:

my_directory
   --- my_file
   --- my_file
   --- my_file

我想要:

my_file
my_file
my_file

15 回答

  • 2
    cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
    

    这个适用于我,它包含所有隐藏文件,而不是将所有文件放在名为"."的根目录中,如tomoe's answer中所示:

  • 0

    使用pax .

    Pax是一个不赞成使用的软件包,但它以完美的方式完成工作 .

    pax -w > mydir.tar mydir
    
  • 27

    我发现最简单的方法:

    cd my_dir && tar -czvf ../my_dir.tar.gz *

  • 16
    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
    
  • 13

    使用tar的 -C 开关:

    tar -czvf my_directory.tar.gz -C my_directory .
    

    -C my_directory 告诉tar将当前目录更改为 my_directory ,然后 . 表示"add the entire current directory"(包括隐藏文件和子目录) .

    确保在执行 . 之前执行 -C my_directory ,否则您将获取当前目录中的文件 .

  • 1

    您也可以像往常一样创建存档并使用以下内容解压缩:

    tar --strip-components 1 -xvf my_directory.tar.gz
    
  • 42

    看看 --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

  • 14

    This Answer应该适用于大多数情况 . 但请注意文件名如何存储在tar文件中,例如 ./file1 而不仅仅是 file1 . 我发现这在使用此方法操作在BuildRoot中用作包文件的tarball时会引起问题 .

    一种解决方案是使用一些Bash globs列出除_944476之外的所有文件,如下所示:

    tar -C my_dir -zcvf my_dir.tar.gz .[^.]* ..?* *
    

    这是我从this answer学到的一个技巧 .

    如果没有匹配 ..?*.[^.]* 的文件,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 globs * ,因此,使用:

    shopt -s dotglob
    cd my_dir
    tar -zcvf ../my_dir.tar.gz *
    cd ..
    shopt -u dotglob
    
  • -3
    cd my_directory
    tar zcvf ../my_directory.tar.gz *
    
  • 549

    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 配置选项将所有文件移出该目录,但这并没有消除 . 目录本身 . 驯服命令变得越来越困难 .

    您可以使用 $(find ...) 向命令添加文件列表(如magnus' answer中),但这可能会导致"file list too long"错误 . 最好的方法是将它与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
    

    非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 -
    
  • -1

    如果它是Unix / Linux系统,并且您关心隐藏文件(将会遗漏),您需要执行以下操作:

    cd my_directory
    tar zcvf ../my_directory.tar.gz * .??*
    

    我不知道在Windows下隐藏文件是什么样的 .

  • 3

    我建议使用以下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 . 它适用于隐藏( . *)元素以及文件名中包含空格的元素 .

  • 0
    # 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=-
    }
    

    安全地处理带有空格或其他异常字符的文件名 . 您可以选择在find命令中添加 -name '*.sql' 或类似的过滤器,以限制包含的文件 .

  • 185
    tar -cvzf  tarlearn.tar.gz --remove-files mytemp/*
    

    如果文件夹是mytemp,那么如果你应用上面的文件,它将压缩并删除文件夹中的所有文件,但保留它单独

    tar -cvzf  tarlearn.tar.gz --remove-files --exclude='*12_2008*' --no-recursion mytemp/*
    

    您可以提供排除模式,也可以指定不查看子文件夹

  • 0
    tar -C my_dir -zcvf my_dir.tar.gz `ls my_dir`
    

相关问题