How do I tar a directory of files and folders without including the directory itself?

前端 未结 18 658
孤城傲影
孤城傲影 2021-01-29 17:04

I typically do:

tar -czvf my_directory.tar.gz my_directory

What if I just want to include everything (including any hidden system files) in my_

相关标签:
18条回答
  • 2021-01-29 17:42

    TL;DR

    find /my/dir/ -printf "%P\n" | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
    

    With some conditions (archive only files, dirs and symlinks):

    find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
    

    Explanation

    The below unfortunately includes a parent directory ./ in the archive:

    tar -czf mydir.tgz -C /my/dir .
    

    You can move all the files out of that directory by using the --transform configuration option, but that doesn't get rid of the . directory itself. It becomes increasingly difficult to tame the command.

    You could use $(find ...) to add a file list to the command (like in magnus' answer), but that potentially causes a "file list too long" error. The best way is to combine it with tar's -T option, like this:

    find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d | tar -czf mydir.tgz --no-recursion -C /my/dir/ -T -
    

    Basically what it does is list all files (-type f), links (-type l) and subdirectories (-type d) under your directory, make all filenames relative using -printf "%P\n", and then pass that to the tar command (it takes filenames from STDIN using -T -). The -C option is needed so tar knows where the files with relative names are located. The --no-recursion flag is so that tar doesn't recurse into folders it is told to archive (causing duplicate files).

    If you need to do something special with filenames (filtering, following symlinks etc), the find command is pretty powerful, and you can test it by just removing the tar part of the above command:

    $ find /my/dir/ -printf "%P\n" -type f -o -type l -o -type d
    > textfile.txt
    > documentation.pdf
    > subfolder2
    > subfolder
    > subfolder/.gitignore
    

    For example if you want to filter PDF files, add ! -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 find

    The command uses printf (available in GNU find) which tells find to print its results with relative paths. However, if you don't have GNU find, this works to make the paths relative (removes parents with 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 -
    
    0 讨论(0)
  • 2021-01-29 17:42

    Simplest way I found:

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

    0 讨论(0)
  • 2021-01-29 17:47
    cd my_directory && tar -czvf ../my_directory.tar.gz $(ls -A) && cd ..
    

    This one worked for me and it's include all hidden files without putting all files in a root directory named "." like in tomoe's answer :

    0 讨论(0)
  • 2021-01-29 17:47
    # 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=-
    }
    

    Safely handles filenames with spaces or other unusual characters. You can optionally add a -name '*.sql' or similar filter to the find command to limit the files included.

    0 讨论(0)
  • 2021-01-29 17:49

    This is what works for me.

    tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -maxdepth 1 -printf '%P ')
    

    You could also use

    tar -cvf my_dir.tar.gz -C /my_dir/ $(find /my_dir/ -mindepth 1 -maxdepth 1 -printf '%P ')
    

    In the first command, find returns a list of files and sub-directories of my_dir. However, the directory my_dir is itself included in that list as '.' The -printf parameter removes the full path including that '.' and also all crlf However the space in the format string '%P ' of printf leaves a remnant in the list of files and sub-directories of my_dir and can be seen by a leading space in the result of the find command.

    That will not be a problem for TAR but if you want to fix this, add -mindepth 1 as in the second command.

    0 讨论(0)
  • 2021-01-29 17:50
     tar -cvzf  tarlearn.tar.gz --remove-files mytemp/*
    

    If the folder is mytemp then if you apply the above it will zip and remove all the files in the folder but leave it alone

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

    You can give exclude patterns and also specify not to look into subfolders too

    0 讨论(0)
提交回复
热议问题