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:
Basic regular expression should work with
\/
. Sadlybsdtar
is incorrectly written here, and does not handle escaping correctly.From bsdtar/subst.c:
rule_text
is a stringchar *
which is passed with the string you pass to-s
option, so it has the string/^\.svn\/patches/__patches
. Theend_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: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:
Any character will work for the
/
.