This does not work:
$ tar -cf /tmp/z.tar -C /space/myroot -s '/^\.svn\/patches/__patches' src .svn/patches
tar: Invalid regular expression: trailing backslash (\)
Also no good:
$ tar -cf /tmp/z.tar -C /space/myroot -s '/^\\.svn\\/patches/__patches' src .svn/patches
tar: Invalid replacement flag _
Every combination of backslashes (up to 4) and quoting gives me one of those two errors. However I know the first one works in sed:
$ tar -cf /tmp/z.tar -C /space/myroot src .svn/patches
$ tar -tf /tmp/z.tar | sed 's/^\.svn\/patches/__patches/'
src/a.c
src/b.c
__patches/A.patch
__patches/B.patch
Also I know I can cop-out and do this:
$ tar -cf /tmp/z.tar -C /space/myroot -s '/^.svn.patches/__patches' src .svn/patches
-- but I don't really want to.
From man bsdtar:
-s pattern
....
where old is a basic regular expression
...
Basic regular expression should work with \/
. Sadly bsdtar
is incorrectly written here, and does not handle escaping correctly.
From bsdtar/subst.c:
end_pattern = strchr(rule_text + 1, *rule_text);
rule_text
is a string char *
which is passed with the string you pass to -s
option, so it has the string /^\.svn\/patches/__patches
. The end_pattern
should point to the last character of the pattern (ie. to the /
in from of /__patches
). However as simple strchr is used, so the first /
found is used (the character in \/
), escaped or not, it is used. The error:
tar: Invalid regular expression: trailing backslash (\)
comes from regcomp trying to parse the regular expression ^\.svn\
(as this is the part stripped between the two /
). As there is nothing behind the trailing backslash \
in the expression, it throws an error (and is correct - a trailing backslash is there). One could think of posting a bug report to bsdtar developers, but it's probably not really worth fixing.
Note that the syntax for -s
is /old/new/
. There is a trailing /
in the pattern, which you are missing. After the last /
you can specify flags.
You can however workaround the issue with:
bsdtar -s '#\.svn/patches#__patches#'
Any character will work for the /
.