1

I have read here Difference between single and double quotes in Bash that single quotes will not allow any kind of interpolation. However I came across a situation where single quotes were actually the only way to interpolate my variable' value. For the sake of an example I created a file named 'test_file' containing

1
2
3
4
5
6
7
8
9
10

Than in the same directory I created a script whose purpose was to extract parts of this file, I called it test.sh and this is its content:

#!/bin/bash
BEGIN=3
END=9

cat test_file | sed -n ''$BEGIN', '$END'p'

Now I tried different setups of the last line like:

cat test_file | sed -n '${BEGIN}, ${END}p'
cat test_file | sed -n '"${BEGIN}", "${END}"p'
cat test_file | sed -n '"$BEGIN", "$END"p'

But none of them worked. My question is: why does it work that way?

Cyrus
  • 84,225
  • 14
  • 89
  • 153
Z.Szymon
  • 337
  • 1
  • 13
  • 4
    Why didn't you try double quotes? – melpomene Jul 27 '19 at 18:25
  • 1
    Your last two just have *literal* double quotes passed to `sed`; they don't "reenable" parameter expansion inside single quotes. – chepner Jul 27 '19 at 18:27
  • 2
    There is no interpolation in your example. `$BEGIN` and `$END` are outside the quotes. They are expanded because of that. The quoted strings are `''` (the empty string), `', '` and `'p'`. – axiac Jul 27 '19 at 18:34
  • With awk: `seq 1 10 | awk 'NR>=begin && NR<=end' begin=3 end=9` – Cyrus Jul 28 '19 at 05:23
  • See: [Difference between single and double quotes in bash](http://stackoverflow.com/q/6697753/3776858) – Cyrus Jul 28 '19 at 05:23

1 Answers1

5

Quotes of both flavors are a shortcut: they cause the enclosed characters to be treated as if they were each escaped by \. The difference between single and double quotes, then, is that double quotes do not escape $ (or following characters which form part of an expansion), allowing parameter and command substitutions to occur (with the results being treated as double-quoted strings as well).

Your first consists of an empty string '', followed by an unquoted expansion, then the literal string ,, the unquoted expansion, and a literal p.

Your second is a single literal sting.

Your third adds literal double quotes around the literal strings ${BEGIN} and ${END}.

The fourth is similar to the third, but drops the literal { and }.

The correct string is

sed -n "$BEGIN, ${END}p"  # sed -n "3, 9p"
chepner
  • 497,756
  • 71
  • 530
  • 681