Names with embedded whitespace


#1

I have some files with embedded whitespace characters that I would like to use as the value of the --exclude option - so far without success. I have tried --exclude="File Name", --exclude="File\ Name",
--exclude="File\\ Name", to no avail. Any suggestions?


#2

I think you need to specify the entire path for this “File\ Name”. For example, if I include on my exclude file $HOME/Documents/*\ *, this will exclude all files that contains spaces in the filenames in the “Documents” folder only. Now, if you do this (in your exclude file or using --exclude) "*\ *", then it will take that as a pattern, so it will exclude all files containing spaces between filenames. If it is a specific pattern, lets say you have a bunch of files named “files 1”, “files 2”, etc., then you can use --exclude="file\ *" and that should exclude all those files named file 1, file 2, etc.; or --exclude="*\ name" should exclude all files of which the name ends in “name” after the first space.

At least for me this worked. I hope it helps.


#4

Actually, I used a full pathname - I wrote "File\ Name" for brevity. In my case (in bash under Linux) no matter what I do, the presence of an embedded space in a full pathname elicits an error from restic - i.e. for a line containing

--exclude="/home/xyz//File Name"

restic complains as follows:

error for exclude pattern: Match: syntax error in pattern

I get the same with "/home/xyz/File\ Name" and "/home/xyz/File\\ Name"


#5

It would seem that one of the backslashes is swallowed up in the last example: there should be two backslashes after File, not just one.


#6

That is weird. I use Xubuntu and I just did this test:

rescript test -r $HOME/Downloads/restic-repo backup $HOME/Projects --exclude="*\ *"

Result:

repository 0576f21e opened successfully, password is correct

Files:           0 new,     0 changed,   114 unmodified
Dirs:            0 new,     2 changed,     0 unmodified
Added to the repo: 756 B

processed 114 files, 945.118 KiB in 0:00
snapshot 6240aae7 saved

There are two files with spaces in the Projects directory and two more in a subdirectory and there were all excluded. Verified mounting the repository and the files with spaces were excluded.


#7

Can you paste the raw command line, complete and unaltered?


You can exclude files with spaces by passing in a space (without escaping by \) to --exclude, you just need to make sure that the shell does not interpret it, typically be surrounding the argument to --exclude by quotes.

Let’s try that with a directory containing two (empty) files (bash on Linux, using restic 0.9.4):

$ touch 'file with spaces'
$ touch file-without-spaces

$ ls -al
total 0
drwxr-xr-x  2 fd0  users  80 Jan 13 09:49  .
drwxrwxrwt 18 root root  440 Jan 13 09:49  ..
-rw-r--r--  1 fd0  users   0 Jan 13 09:49  file-without-spaces
-rw-r--r--  1 fd0  users   0 Jan 13 09:49  file with spaces

If we now save the directory, restic will save both files:

$ restic backup .
open repository
repository b828865b opened successfully, password is correct
created new cache in /home/fd0/.cache/restic

Files:           2 new,     0 changed,     0 unmodified
Dirs:            0 new,     0 changed,     0 unmodified
Added to the repo: 603 B

processed 2 files, 0 B in 0:00
snapshot d47bb8eb saved

We can check with ls:

$ restic ls -l latest
repository b828865b opened successfully, password is correct
snapshot d47bb8eb of [/tmp/testdata] filtered by [] at 2019-01-13 09:49:58.303526126 +0100 CET):
-rw-r--r--  1000   100      0 2019-01-13 09:49:46 /file with spaces
-rw-r--r--  1000   100      0 2019-01-13 09:49:49 /file-without-spaces

If we now pass the string * * to --exclude, restic will exclude all files (and directories) containing at least one space somewhere in the file name:

$ restic backup --exclude '* *' .
open repository
repository b828865b opened successfully, password is correct

Files:           0 new,     0 changed,     1 unmodified
Dirs:            0 new,     0 changed,     0 unmodified
Added to the repo: 309 B

processed 1 files, 0 B in 0:00
snapshot 8386b894 saved

Checking again with ls, the file file with spaces wasn’t saved:

$ restic ls -l latest
repository b828865b opened successfully, password is correct
snapshot 8386b894 of [/tmp/testdata] filtered by [] at 2019-01-13 09:50:09.889296862 +0100 CET):
-rw-r--r--  1000   100      0 2019-01-13 09:49:49 /file-without-spaces

I cannot reproduce what you’re describing. Two consecutive slashes in an exclude pattern work just fine:

$ restic backup --exclude '/tmp//testdata/*without*' .
open repository
repository b828865b opened successfully, password is correct

Files:           1 new,     0 changed,     0 unmodified
Dirs:            0 new,     0 changed,     0 unmodified
Added to the repo: 306 B

processed 1 files, 0 B in 0:00
snapshot 229ca375 saved

The file file-without-spaces isn’t saved:

$ restic ls -l latest
repository b828865b opened successfully, password is correct
snapshot 229ca375 of [/tmp/testdata] filtered by [] at 2019-01-13 09:57:46.210068283 +0100 CET):
-rw-r--r--  1000   100      0 2019-01-13 09:49:46 /file with spaces

#8

@fd0 could the restic version have something to do with it?

Also, if I’m not mistaken you should specify the file extension, right? Maybe that could be it, using "File\ Name" instead of "File\ Name.txt".


#9

I’ve tested with 0.9.4, we haven’t changed that logic in a while so I don’t think the version matters. I suspect just a tiny detail (which wasn’t obvious from the pasted commands) went wrong here.

If the file you’re trying to exclude has an extension then you either need to specify it (or a wildcard like *) at the end of the pattern.


#10

You meant “restic will exclude,” I think.


#11

You’re right, thanks!


#12

Well, I must apologize to everybody for wasting your time, for it does work. I don’t know what happened - whether it was a rogue, non-printable character that snuck its way into the command, or what. For the same of completeness, the command line that I used is the following:

restic -r sftp:remote:rep backup /home/xyz --exclude="/home/xyz/**/file1.dat" 
                                           --exclude="/home/xyz/.screen/*"
                                           --exclude="/home/xyz/Embedded Blank/SomeDirs*"

Once again, my apologies for the wild goose chase.