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.
