Skip to content

Commit 1ad6f30

Browse files
committed
;doc:Special characters: rewrite [#2468]
1 parent cca39bc commit 1ad6f30

File tree

1 file changed

+37
-55
lines changed

1 file changed

+37
-55
lines changed

hledger/hledger.m4.md

Lines changed: 37 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -275,86 +275,78 @@ feel free to skip these until you need them.
275275

276276
## Special characters
277277

278-
Here we touch on shell escaping/quoting rules, and give some examples.
279-
This is a slightly complicated topic which you may not need at first,
280-
but you should be aware of it, so you can return here when needed.
278+
In commands you type at the command line,
279+
certain characters have special meaning and sometimes need to be "escaped" or "quoted",
280+
by prefixing backslashes or enclosing in quotes.
281281

282-
If you are able to minimise the use of special characters in your data,
283-
you won't need escaping as much, and your command lines will be simpler.
284-
For example, avoiding spaces in account names, and using an ISO-4217 currency code like `USD`
285-
instead of the `$` currency symbol, can be helpful.
282+
If you are able to minimise the use of special characters in your data, you won't have to deal with this as much.
283+
For example, you could use `-` or `_` instead of spaces in account names,
284+
and you could use the `USD` currency code instead of the `$` currency symbol in amounts.
286285

287-
But if you want to use spaced account names and `$`, go right ahead; escaping isn't a big deal.
286+
But if you prefer to use spaced account names and `$`, it's fine.
287+
Just be aware of this topic so you can check this doc when needed.
288+
(Note it is written mainly for unix systems; some details might need to be adapted if you're on Windows.)
288289

289290
### Escaping shell special characters
290291

291-
At the command line, characters which have special meaning for your shell
292-
must be "shell-escaped" (AKA "quoted") if you want hledger to see them.
293-
Often these include space, `<`, `>`, `(`, `)`, `|`, `\`, `$` and/or `%`.
292+
These are some characters which may have special meaning to your shell (the program which interprets command lines):
294293

295-
For example, to match an account name containing the phrase "credit card",
296-
don't write this:
294+
- SPACE, `<`, `>`, `(`, `)`, `|`, `\`, `%`
295+
- `$` if followed by a word character
297296

297+
So for example, to match an account name containing spaces, like "credit card", don't write:
298298
```cli
299299
$ hledger register credit card
300300
```
301301

302-
In that command, "credit" and "card" are treated as separate query arguments (described below),
303-
so this would match accounts containing either word.
304-
Instead, enclose the phrase in double or single quotes:
305-
302+
Instead, enclose the name in quotes:
306303
```cli
307-
$ hledger register "credit card"
304+
$ hledger register 'credit card'
308305
```
309306

310-
In Unix shells, writing a backslash before the character can also work. Eg:
307+
Single quotes are the most reliable. Or use double quotes if you want your shell to treat `$` as a variable interpolation, as in:
308+
```cli
309+
$ hledger register "assets:$SOMEACCT"
310+
```
311311

312+
On unix systems (but not Windows), a backslash before the space can also work:
312313
```cli
313314
$ hledger register credit\ card
314315
```
315316

316-
Some shell characters still have a special meaning inside double quotes, such as the dollar sign (`$`).
317-
Eg in `"assets:$account"`, the bash shell would replace `$account` with the value of a shell variable with that name.
318-
When you don't want that, use single quotes, which escape more strongly:
317+
On Windows systems, if you are using a Command window rather than Powershell, use double quotes (not single quotes or backslash).
319318

319+
Since hledger's query arguments are [regular expressions] (described below), you can also fill that gap with `.` which matches any character:
320320
```cli
321-
$ hledger balance 'assets:$account'
321+
$ hledger register credit.card
322322
```
323323

324-
### Escaping on Windows
325-
326-
If you are using hledger in a Powershell or Command window on Microsoft Windows, the escaping rules are different:
327-
328-
- In a Powershell window (`powershell`, blue background), you must use double quotes or single quotes (not backslash).
329-
- In a Command window (`cmd`, black background), you must use double quotes (not single quotes or backslash).
330-
331-
The next two sections were written for Unix-like shells, so might need to be adapted if you're using `cmd` or `powershell`. (Edits welcome.)
332324

333325
### Escaping regular expression special characters
334326

335-
Many hledger arguments are [regular expressions] (described below), and these too have characters which cause special effects.
336-
Some of those characters are `.`, `^`, `$`, `[`, `]`, `(`, `)`, `|`, and `\`.
337-
When you don't want these to cause special effects, you can "regex-escape" them by writing `\` (a backslash) before them.
338-
But since backslash is also special to the shell, you may need to also shell-escape the backslashes.
339-
Note that `$` only has special meaning to the shell if followed by a word character indicating a variable name.
340-
When appearing alone at the end of a word as in `cur:\\$` the dollar sign is not considered special and does not *have* ta be escaped.
327+
Some characters also have special meaning in [regular expressions], which hledger's arguments often are. Those include:
341328

342-
Eg, in the bash shell, to match a literal `$` sign, you could write:
329+
- `.`, `^`, `$`, `[`, `]`, `(`, `)`, `|`, `\`
343330

331+
To escape one of these, write `\` before it.
332+
But note this is in addition to the shell escaping above.
333+
So for characters which are special to both shell and regular expressions, like `\` and `$`, you will sometimes need two levels of escaping.
334+
335+
For example, a balance report that uses a `cur:` query restricting it to just the $ currency, should be written like this:
344336
```cli
345337
$ hledger balance cur:\\$
346338
```
339+
Explanation:
340+
1. Add a backslash `\` before the dollar sign `$` to protect it from regular expressions (so it will be matched literally with no special meaning).
341+
2. Add another backslash before that backslash, to protect it from the shell (so the shell won't consume it).
342+
3. `$` doesn't need to be protected from the shell in this case, because it's not followed by a word character; but it would be harmless to do so.
347343

348-
The escape here is to pass through a literal escape, the dollar sign does not have to be escaped because it is at the end of a word and hence can't be interpreted as a shell variable.
349-
350-
Alternatively, use single quotes to avoid the special meanings of shell characters and see more visually what value will be passed through:
351-
344+
But here's another way to write that, which tends to be easier:
345+
add backslashes to escape from regular expressions, then enclose with quotes to escape from the shell:
352346
```cli
353-
$ hledger balance 'cur:\$'
347+
$ hledger balance cur:'\$'
354348
```
355349

356-
Here hledger will get a query string of `\$`, which is a regex escaped and hence will match a literal dollar sign.
357-
358350
### Escaping in other situations
359351

360352
hledger options and arguments are sometimes used in places other than the command line, with different escaping rules.
@@ -373,16 +365,6 @@ For example, backslash-quoting generally does not work there. Here are some more
373365
[argument file]: #argument-files
374366
[config file]: #config-file
375367

376-
### Using a wild card
377-
378-
When escaping a special character is too much hassle (or impossible), you can often just write `.` (period) instead.
379-
In regular expressions, this means "accept any character here".
380-
Eg:
381-
382-
```cli
383-
$ hledger register credit.card
384-
```
385-
386368
## Unicode characters
387369

388370
hledger is expected to handle non-ascii characters correctly:

0 commit comments

Comments
 (0)