10

Because of specifics of my archiving needs I am not comfortable with solid tar.gz archives and use 7z instead.

I use the following command to do this:

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=off ~/my/folder.7z ~/my/folder/*

To create an archive of everything inside ~/my/folder/ as the ~/my/folder.7z file.

But ~/my/folder/.hiddenFolder doesm't get into the archive then. How to fix this? Isn't * supposed to return all the files and folders?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Ivan
  • 17,368
  • 35
  • 93
  • 118
  • 1
    You are using bash path expansion by last `*`, try removing it, 7z should archive the whole directory. – enzotib Nov 02 '11 at 22:44
  • @enzotib but I don't want the directory in the archive, only what's inside it. And that's why I tagged the question for `bash` - maybe I am using "bash path expansion" a wrong way? – Ivan Nov 02 '11 at 22:51
  • Had a similar problem, solved it by placing single quotes around the path. That way, the `*` is handled by 7z (and not by bash). – Klaws Oct 01 '20 at 08:26

4 Answers4

11

TL;DR

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=off ~/my/folder.7z ~/my/folder/.

More examples

Example directory structure

test1
├── .hidden
└── normal.txt

0 directories, 2 files

Try following commands

  1. Root folder with all its contents.

    7za a test1_a.7z ~/test1/
    

    gives

        Date      Time    Attr         Size   Compressed  Name
    ------------------- ----- ------------ ------------  ------------------------
    2017-08-06 09:23:51 D....            0            0  test1
    2017-08-06 09:23:44 ....A            0            0  test1/.hidden
    2017-08-06 09:23:51 ....A            0            0  test1/normal.txt
    ------------------- ----- ------------ ------------  ------------------------
    2017-08-06 09:23:51                  0            0  2 files, 1 folders
    
  2. No root folder and no hidden files

    7za a test1_b.7z ~/test1/*
    

    gives

       Date      Time    Attr         Size   Compressed  Name
    ------------------- ----- ------------ ------------  ------------------------
    2017-08-06 09:23:51 ....A            0            0  normal.txt
    ------------------- ----- ------------ ------------  ------------------------
    2017-08-06 09:23:51                  0            0  1 files
    
  3. No root folder but hidden files are included (it's what we usually want)

    7za a test1_c.7z ~/test1/.
    

    gives

       Date      Time    Attr         Size   Compressed  Name
    ------------------- ----- ------------ ------------  ------------------------
    2017-08-06 09:23:44 ....A            0            0  .hidden
    2017-08-06 09:23:51 ....A            0            0  normal.txt
    ------------------- ----- ------------ ------------  ------------------------
    2017-08-06 09:23:51                  0            0  2 files
    
stil
  • 211
  • 2
  • 2
8

If you want the contents of a single directory, an easy method is to change to it first:

cd ~/my/folder
7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=off ~/my/folder.7z .

What you saw is that * expands to the list of names of files that don't begin with a .. That's the documented behavior, and it's the main reason why files whose name begins with a . are said to be hidden (the other is that ls doesn't show them by default).

There's no really convenient portable way to list all files in a directory. You can use

~/my/folder/..?* ~/my/folder/.[!.]* ~/my/folder/*

but if there is no file matching one of the patterns then the pattern will remain unexpanded. In bash, you can set the dotglob option to avoid treating a leading . specially (. and .. are still excluded from the matches):

shopt -s dotglob
7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=off ~/my/folder.7z ~/my/folder/*

In ksh, or in bash if you set the extglob option (or in zsh if you set the ksh_glob option), you can write a pattern that matches all files except . and ..:

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=off ~/my/folder.7z ~/my/folder/@(..?*|.[!.]*|*)

In zsh, there's a simpler way of saying that . must not be treated specially in a pattern:

7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=off ~/my/folder.7z ~/my/folder/*(D)
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
5

No, * is not supposed to return all files. It returns only visible ones.

The easier solution is:

cd ~/my/folder
7z a -t7z -m0=lzma -mx=9 -mfb=64 -md=32m -ms=off ~/my/folder.7z .
andcoz
  • 16,830
  • 3
  • 38
  • 45
0

I extracted my zip archives using 7z (in Linux), I have a folder full of zips.

I have used:

7z x *.zip -o* to extract the zip files

I need to figure out: 7z a {folders from above command} -r

Keeping the above in mind, I want to use the 7z a command to create a 7z archive, but using the folder name that was created in the extraction part.  How can that be done?

Friend
  • 1
  • 1
  • If you have a new question, please ask it by clicking the [Ask Question](https://unix.stackexchange.com/questions/ask) button. Include a link to this question if it helps provide context. - [From Review](/review/late-answers/423326) – G-Man Says 'Reinstate Monica' Sep 13 '22 at 05:10