Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to print out the lines of a file between two indices in a Bash script. I have the file name and indices as variables

I tried doing this

sed -n "$2,$3p" $1

sed: -e expression #1, char 4: invalid usage of line address 0

but I got an error. How do I do this?

share|improve this question
What are $2 and $3's values? What is the error message? – manatwork Dec 31 '13 at 16:33
@manatwork $2 and $3 are the second and third input arguments. – user2798694 Dec 31 '13 at 16:35
“0,addr2 (…) This works only when addr2 is a regular expression.” – man sed. From the error message we found out $2 is 0. So, what is $3's value? – manatwork Dec 31 '13 at 16:38
up vote 4 down vote accepted

OK, the main issue here is that there is no such thing as line 0. sed starts counting lines from 1. Presumably, assuming the rest of your script is OK, this should work:

#!/usr/bin/env bash
sed -n "$2,$3p" "$1"

I tried the script above on this file:

$ cat file
line 1
line 2
line 3
line 4
line 5
line 6
$ ./foo.sh file 3 5
line 3
line 4
line 5
$ ./foo.sh file 0 5
sed: -e expression #1, char 4: invalid usage of line address 0
$ ./foo.sh file 1 3
line 1
line 2
line 3

From man sed (thanks @manatwork):


Start out in "matched first address" state, until addr2 is found. This is similar to 1,addr2, except that if addr2 matches the very first line of input the 0,addr2 form will be at the end of its range, whereas the 1,addr2 form will still be at the beginning of its range. This works only when addr2 is a regular expression.

So, this should work as well:

$ a.sh file 0 "/line 3/"
line 1
line 2
line 3

If you are using normal named variables, it will fail because your shell has no way of knowing where the variable's name ends and the sed commands begin. For example:

foo=1; sed -n "$foop"

will print nothing since the shell will treat $foop as the variable name. To get around that, use curly braces:

$ foo=1; sed -n "${foo}p" file
line 1
share|improve this answer
thanks, this works fine using the nth variable format. However if I use stored variables like $a, it doesn't. – user2798694 Dec 31 '13 at 16:48
Maybe you could add an example for the address 0 case I quoted in my comment: ./foo.sh file 0 /5/. – manatwork Dec 31 '13 at 16:49
@manatwork I already fixed that, I guess it should have worked if i didn't have zero in the input. – user2798694 Dec 31 '13 at 16:51
@manatwork I can't get it to work with any variation of sed -n '0,foo'. If you know how this works, feel free to edit the answer. – terdon Dec 31 '13 at 17:06
“foo” is not valid regular expression. Should be “/foo/”: sed -n '0,/foo/'. – manatwork Dec 31 '13 at 17:26

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.