Home > database >  tar --files-from with wildcard inside the list
tar --files-from with wildcard inside the list

Time:01-05

I'm trying to compress list of files from a text file (include.txt):

/var/dir/1/some_file_number*.txt
/var/dir/1/some_file_number*.log

and exclude from a list (exclude.txt):

/var/dir/1/some_file_number_exclude*.*

with command

tar -cf archive.tar --files-from="/to/my/dir/include.txt" --exclude-from="/to/my/dir/exclude.txt"

It seems to work for the --exclude-from, but doesn't for --files-from, I gets error saying that:

tar: /var/dir/1/some_file_number*.txt: Warning: Cannot stat: No such file or directory
tar: /var/dir/1/some_file_number*.log: Warning: Cannot stat: No such file or directory

Seems like tar couldn't expand the asterisk in --files-from, any idea how to fix this?

CodePudding user response:

You can create a function that expands glob patterns from a file, and execute it inside process substitutions.

function expand_glob_file {
    local patterns __
    readarray -t patterns < "$1" || return

    for __ in "${patterns[@]}"; do
        compgen -G "$__"
    done
}

tar -cf archive.tar --files-from=<(expand_glob_file /to/my/dir/include.txt) --exclude-from=<(expand_glob_file /to/my/dir/exclude.txt)

CodePudding user response:

It seems like tar doesn't support pattern matching when creating an archive. From this documentation:

There are no inclusion members in create mode (‘--create’ and ‘--append’), since in this mode the names obtained from the command line refer to files, not archive members.

For other operations such as --extract, you could use the --wildcards flag but apparently creating an archive is an exception.

One idea is you could first expand the wildcards in your include file using something like

xargs -I @ bash -c "printf '%s\n' @" < /to/my/dir/include.txt > /tmp/include.txt
mv /tmp/include.txt /to/my/dir/include.txt

and then run your tar command from before. Note: this doesn't handle spaces in file paths well (and possibly many other things since it relies on shell expansion), but konsolebox's answer seems to support that.

  •  Tags:  
  • Related